home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DBio.more / UGridView.cp < prev    next >
Text File  |  1996-07-05  |  113KB  |  3,614 lines

  1. //----------------------------------------------------------------------------------------
  2. // UGridView.cp 
  3. // Copyright © 1987-1993 by Apple Computer Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UGRIDVIEW__
  7. #include <UGridView.h>
  8. #endif
  9.  
  10. #ifndef __STDIO__
  11. #include <stdio.h>
  12. #endif
  13.  
  14. #ifndef __UGEOMETRY__
  15. #include <UGeometry.h>
  16. #endif
  17.  
  18. #ifndef __ERRORS__
  19. #include <Errors.h>
  20. #endif
  21.  
  22. #ifndef __TOOLUTILS__
  23. #include <ToolUtils.h>
  24. #endif
  25.  
  26. #ifndef __PACKAGES__
  27. #include <Packages.h>
  28. #endif
  29.  
  30. #ifndef __STDLIB__
  31. #include <stdlib.h>
  32. #endif
  33.  
  34. #ifndef __UADORNERS__
  35. #include <UAdorners.h>
  36. #endif
  37.  
  38. #ifndef __UMACAPPUTILITIES__
  39. #include <UMacAppUtilities.h>
  40. #endif
  41.  
  42. #ifndef __UMEMORY__
  43. #include <UMemory.h>
  44. #endif
  45.  
  46. #ifndef __UDEBUG__
  47. #include <UDebug.h>
  48. #endif
  49.  
  50. #ifndef __UMACAPPGLOBALS__
  51. #include <UMacAppGlobals.h>
  52. #endif
  53.  
  54. #ifndef __FONTS__
  55. #include <Fonts.h>
  56. #endif
  57.  
  58. //----------------------------------------------------------------------------------------
  59. RgnHandle pPixelsToHighlight;
  60. RgnHandle pPreviousSelection;
  61. RgnHandle pDifference;
  62. RgnHandle pVisibleCells;
  63. RgnHandle pInvalidateRgn;
  64.  
  65.  
  66. //========================================================================================
  67. // GLOBAL Procedures
  68. //========================================================================================
  69. #undef Inherited
  70.  
  71. //----------------------------------------------------------------------------------------
  72. // InitUGridView: 
  73. //----------------------------------------------------------------------------------------
  74. #pragma segment GVInit
  75.  
  76. void InitUGridView()
  77. {
  78.     if (qTemplateViews)
  79.     {
  80.         // So the linker doesn't dead strip these 
  81.         macroDontDeadStrip(TGridView);
  82.         macroDontDeadStrip(TTextGridView);
  83.         macroDontDeadStrip(TTextListView);
  84.  
  85.         RegisterStdType("TGridView", kStdGridView);
  86.         RegisterStdType("TTextGridView", kStdTextGridView);
  87.         RegisterStdType("TTextListView", kStdTextListView);
  88.     }
  89.  
  90.     pPixelsToHighlight = MakeNewRgn();
  91.     pPreviousSelection = MakeNewRgn();
  92.     pDifference = MakeNewRgn();
  93.     pVisibleCells = MakeNewRgn();
  94.     pInvalidateRgn = MakeNewRgn();
  95.     gUGridViewInitialized = TRUE;
  96. } // InitUGridView 
  97.  
  98.  
  99. //========================================================================================
  100. // CLASS TRunArray
  101. //========================================================================================
  102. #undef Inherited
  103. #define Inherited TObject
  104.  
  105. #pragma segment GVOpen
  106. DefineClass(TRunArray, Inherited);
  107.  
  108. //----------------------------------------------------------------------------------------
  109. // TRunArray constructor
  110. //----------------------------------------------------------------------------------------
  111. #pragma segment GVOpen
  112.  
  113. TRunArray::TRunArray()
  114. {
  115.     fChunks = NULL;
  116.     fLastChunk = 0;
  117.     fLastIndex = 1;
  118.     fLastItem = 0;
  119.     fLastTotal = 0;
  120.     fNoOfChunks = 0;
  121.     fNoOfItems = 0;
  122.     fTotal = 0;
  123. } // TRunArray::TRunArray
  124.  
  125. //----------------------------------------------------------------------------------------
  126. // TRunArray::IRunArray: 
  127. //----------------------------------------------------------------------------------------
  128. #pragma segment GVOpen
  129.  
  130. void TRunArray::IRunArray()
  131. {
  132.     this->IObject();
  133.  
  134.     FailInfo fi;
  135.     Try(fi)
  136.     {
  137.         fChunks = (ChunkArrayHandle)(NewPermHandle(0));
  138.         fi.Success();
  139.     }
  140.     else
  141.     {
  142.         this->Free();
  143.         fi.ReSignal();
  144.     }
  145. } // TRunArray::IRunArray 
  146.  
  147. //----------------------------------------------------------------------------------------
  148. // TRunArray::Free: 
  149. //----------------------------------------------------------------------------------------
  150. #pragma segment GVClose
  151.  
  152. void TRunArray::Free()                    // override 
  153. {
  154.     fChunks = (ChunkArrayHandle)DisposeIfHandle((Handle)fChunks);// Blow chunks 
  155.  
  156.     Inherited::Free();
  157. } // TRunArray::Free 
  158.  
  159. //----------------------------------------------------------------------------------------
  160. // TRunArray::DeleteItems: 
  161. //----------------------------------------------------------------------------------------
  162. #pragma segment GVNonRes
  163.  
  164. void TRunArray::DeleteItems(short firstItem,
  165.                                    short noOfItems)
  166. {
  167.     long offset;
  168.     long result;
  169.     short i;
  170.     short num;
  171.     long theTotal;
  172.     short index;
  173.  
  174.     if (!FindChunk(firstItem, num, index, theTotal))
  175.     {
  176. #if qDebug
  177.         CStr255 theString;
  178.         ConcatNumber("Unable to find chunk for item ", firstItem, theString);
  179.         ProgramBreak(theString);
  180. #endif
  181.  
  182.         return;
  183.     }
  184.  
  185.     for (i = 1; i <= noOfItems; ++i)
  186.     {
  187.         fTotal -= (*fChunks)[num].value;
  188.  
  189.         --(*fChunks)[num].count;
  190.  
  191.         if ((*fChunks)[num].count < index)
  192.         {
  193.             index = 1;
  194.             if ((*fChunks)[num].count == 0)
  195.             {
  196.                 // need to delete that chunk 
  197.                 offset = num * sizeof(RunArrayChunk);
  198.                 result = Munger((Handle)fChunks, offset, NULL, sizeof(RunArrayChunk), &result, 0);
  199.                 FailMemError();
  200.                 --fNoOfChunks;
  201.  
  202.                 // Thanks JDR 10/28/89 
  203.                 // see if we can consolidate chunks 
  204.                 if ((num > 0) && (num < fNoOfChunks) && ((*fChunks)[num - 1].value == (*fChunks)[num].value))
  205.                 {
  206.                     index = (*fChunks)[num - 1].count + 1;
  207.                     (*fChunks)[num - 1].count += (*fChunks)[num].count;
  208.                     // need to delete that chunk 
  209.                     result = Munger((Handle)fChunks, offset, NULL, sizeof(RunArrayChunk), &result, 0);
  210.                     FailMemError();
  211.                     --num;
  212.                     --fNoOfChunks;
  213.                 }
  214.             }
  215.             else
  216.                 ++num;
  217.         }
  218.     }
  219.  
  220.     fNoOfItems -= noOfItems;
  221.  
  222.     // reset the cache 
  223.     fLastItem = 0;
  224.     fLastChunk = 0;
  225.     fLastTotal = 0;
  226.     fLastIndex = 1;
  227. } // TRunArray::DeleteItems 
  228.  
  229. //----------------------------------------------------------------------------------------
  230. // TRunArray::FindChunk: 
  231. //----------------------------------------------------------------------------------------
  232. #pragma segment GVRes
  233.  
  234. Boolean TRunArray::FindChunk(short item,
  235.                                     short& chunk,
  236.                                     short& indexInChunk,
  237.                                     long& theTotal)
  238. {
  239.     short thisItem;
  240.     short count;
  241.     short delta;
  242.     Boolean result;
  243.  
  244.     if ((fNoOfChunks <= 0) || (item > fNoOfItems) || (item <= 0))
  245.     {
  246.         chunk = 0;
  247.         theTotal = 0;
  248.         indexInChunk = 0;
  249.         result = FALSE;
  250.         item = 0;
  251.     }
  252.     else if (item == fLastItem)
  253.     {
  254.         // check for the very easy case 
  255.         chunk = fLastChunk;
  256.         theTotal = fLastTotal;
  257.         indexInChunk = fLastIndex;
  258.         result = TRUE;
  259.     }
  260.     else
  261.     {
  262.         delta = abs(item - fLastItem);
  263.  
  264.         if ((delta >= item) || (item <= (*fChunks)[0].count))
  265.         {
  266.             // start from the first chunk 
  267.             chunk = 0;
  268.             theTotal = 0;
  269.             thisItem = 0;
  270.         }
  271.         else if (delta > (fNoOfItems - item + 1))
  272.         {
  273.             // start from the end chunk 
  274.             chunk = fNoOfChunks - 1;
  275.             count = (*fChunks)[chunk].count;
  276.             theTotal = fTotal - (count * (*fChunks)[chunk].value);
  277.             thisItem = fNoOfItems - count;
  278.         }
  279.         else
  280.         {                                        // start from the previous values 
  281.             chunk = fLastChunk;
  282.             theTotal = fLastTotal;
  283.             thisItem = fLastItem - fLastIndex;
  284.         }
  285.  
  286.         if (item > thisItem)
  287.         {
  288.             while ((thisItem + (*fChunks)[chunk].count) < item)
  289.             {
  290.                 count = (*fChunks)[chunk].count;
  291.                 theTotal += count * (*fChunks)[chunk].value;
  292.                 thisItem += count;
  293.                 ++chunk;
  294.             }
  295.         }
  296.         else
  297.         {
  298.             do
  299.             {
  300.                 --chunk;
  301.                 count = (*fChunks)[chunk].count;
  302.                 theTotal -= count * (*fChunks)[chunk].value;
  303.                 thisItem -= count;
  304.             } while (thisItem >= item);
  305.         }
  306.         indexInChunk = item - thisItem;
  307.         result = TRUE;
  308.     }
  309.     // cache the last values 
  310.     fLastItem = item;
  311.     fLastChunk = chunk;
  312.     fLastTotal = theTotal;
  313.     fLastIndex = indexInChunk;
  314.  
  315.     return result;
  316. } // TRunArray::FindChunk 
  317.  
  318. //----------------------------------------------------------------------------------------
  319. // TRunArray::FindItem: 
  320. //----------------------------------------------------------------------------------------
  321. #pragma segment GVRes
  322.  
  323. short TRunArray::FindItem(long theTotal)
  324. {
  325.     short result = 0;
  326.     if ((theTotal >= 0) && (theTotal <= fTotal) && (fNoOfChunks > 0))
  327.         if (fNoOfChunks == 1)
  328.         {
  329.             if ((*fChunks)[0].value > 0)
  330.                 result = (short)Min(((theTotal - 1) / (*fChunks)[0].value) + 1, fNoOfItems);//!!! Cast
  331.         }
  332.         else if (theTotal == 0)
  333.             result = 1;
  334.         else
  335.         {
  336.             ++theTotal;
  337.             short runningCount = 0;
  338.             for (short i = 0; i <= fNoOfChunks - 1; ++i)
  339.             {
  340.                 RunArrayChunk chunk = (*fChunks)[i];
  341.  
  342.                 theTotal -= chunk.value * chunk.count;
  343.                 runningCount += chunk.count;
  344.                 if (theTotal <= 0)
  345.                 {
  346.                     result = (short)(runningCount + (theTotal / chunk.value));//!!! Cast
  347.                     return result;
  348.                 }
  349.             }
  350.             result = fNoOfItems;
  351.         }
  352.     return result;
  353. } // TRunArray::FindItem 
  354.  
  355. //----------------------------------------------------------------------------------------
  356. // TRunArray::GetValue: 
  357. //----------------------------------------------------------------------------------------
  358. #pragma segment GVRes
  359.  
  360. short TRunArray::GetValue(short item)
  361. {
  362.     short num;
  363.     long theTotal;
  364.     short index;
  365.  
  366.     if (fNoOfChunks == 1)
  367.         return (*fChunks)[0].value;
  368.     else if (this->FindChunk(item, num, index, theTotal))
  369.         return (*fChunks)[num].value;
  370.     else
  371.         return 0;
  372. } // TRunArray::GetValue 
  373.  
  374. //----------------------------------------------------------------------------------------
  375. // TRunArray::InsertItems: 
  376. //----------------------------------------------------------------------------------------
  377. #pragma segment GVRes
  378.  
  379. void TRunArray::InsertItems(short firstItem,
  380.                                    short noOfItems,
  381.                                    short value)
  382. {
  383.     short num;
  384.     long theTotal;
  385.     short index;
  386.     long oldSize;
  387.     long result;
  388.     struct
  389.     {
  390.         RunArrayChunk chunk1;
  391.         RunArrayChunk chunk2;
  392.     } tempChunks;
  393.  
  394.  
  395.     // Check if we can just increment the last size count 
  396.  
  397.     if ((firstItem > fNoOfItems) && (fNoOfChunks > 0) && ((*fChunks)[fNoOfChunks - 1].value == value))
  398.         (*fChunks)[fNoOfChunks - 1].count += noOfItems;
  399.  
  400.     // check if we can increment any size count 
  401.     else if (this->FindChunk(firstItem, num, index, theTotal) && ((*fChunks)[num].value == value))
  402.  
  403.         (*fChunks)[num].count += noOfItems;
  404.  
  405.     // check if this would actually fit as the last item in the previous chunk 
  406.     // Thanks Martin Frické, 10/31/89
  407.  
  408.     else if ((num > 0) && (index == 1) && ((*fChunks)[num - 1].value == value))
  409.         (*fChunks)[num - 1].count += noOfItems;
  410.  
  411.     // We need to create a new chunk, possibly two 
  412.     else
  413.     {
  414.         oldSize = GetHandleSize((Handle)fChunks);
  415.         tempChunks.chunk1.value = value;
  416.         tempChunks.chunk1.count = noOfItems;
  417.  
  418.         if ((index <= 1) || (firstItem > fNoOfItems))
  419.         {
  420.             // need to add one chunk 
  421.             if (firstItem > fNoOfItems)
  422.                 num = fNoOfChunks;                // add a row on the end 
  423.  
  424.             result = Munger((Handle)fChunks, num * sizeof(RunArrayChunk), NULL, 0, &tempChunks, sizeof(RunArrayChunk));
  425.             FailMemError();
  426.             ++fNoOfChunks;
  427.         }
  428.         else
  429.         {
  430.             // need to add two 
  431.             tempChunks.chunk2.count = (*fChunks)[num].count - index + 1;
  432.             tempChunks.chunk2.value = (*fChunks)[num].value;
  433.             (*fChunks)[num].count = index - 1;
  434.             result = Munger((Handle)fChunks, (num + 1) * sizeof(RunArrayChunk), NULL, 0, &tempChunks, 2 * sizeof(RunArrayChunk));
  435.             FailMemError();
  436.             fNoOfChunks += 2;
  437.         }
  438.         if (GetHandleSize((Handle)fChunks) <= oldSize)
  439.             Failure(memFullErr, 0);
  440.     }
  441.  
  442.     // reset the cache 
  443.     fLastItem = 0;
  444.     fLastChunk = 0;
  445.     fLastTotal = 0;
  446.     fLastIndex = 1;
  447.  
  448.     fNoOfItems += noOfItems;
  449.     fTotal += noOfItems * value;
  450. } // TRunArray::InsertItems 
  451.  
  452. //----------------------------------------------------------------------------------------
  453. // TRunArray::SumValues: 
  454. //----------------------------------------------------------------------------------------
  455. #pragma segment GVRes
  456.  
  457. long TRunArray::SumValues(short firstItem,
  458.                                  short noOfItems)
  459. {
  460.     short chunk;
  461.     short indexInChunk;
  462.     long total;
  463.     long precedingTotal;
  464.     long result;
  465.  
  466.     result = 0;
  467.  
  468.     if (fNoOfChunks == 1)
  469.         result = noOfItems * (*fChunks)[0].value;
  470.     else if (firstItem == 1)
  471.     {
  472.         if (this->FindChunk(noOfItems, chunk, indexInChunk, total))
  473.             result = total + (indexInChunk * (*fChunks)[chunk].value);
  474.     }
  475.     else if (this->FindChunk(firstItem, chunk, indexInChunk, total))
  476.     {
  477.         precedingTotal = total + ((indexInChunk - 1) * (*fChunks)[chunk].value);
  478.         if (this->FindChunk(firstItem + noOfItems - 1, chunk, indexInChunk, total))
  479.             result = total + (indexInChunk * ((*fChunks)[chunk].value) - precedingTotal);
  480.     }
  481.     return result;
  482. } // TRunArray::SumValues 
  483.  
  484.  
  485. //========================================================================================
  486. // CLASS TGridView
  487. //========================================================================================
  488. #undef Inherited
  489. #define Inherited TView
  490.  
  491. #pragma segment GVOpen
  492. DefineClass(TGridView, Inherited);
  493.  
  494. //----------------------------------------------------------------------------------------
  495. // TGridView constructor
  496. //----------------------------------------------------------------------------------------
  497. #pragma segment GVOpen
  498.  
  499. TGridView::TGridView()
  500. {
  501.     fNumOfRows = 0;
  502.     fNumOfCols = 0;
  503.  
  504.     fAdornRows = FALSE;
  505.     fAdornCols = FALSE;
  506.     fRowInset = 0;
  507.     fColInset = 0;
  508.     fColWidths = NULL;
  509.     fRowHeights = NULL;
  510.  
  511.     fSelections = NULL;
  512.     fHLRegion = NULL;
  513.     fTemporarySelections = NULL;
  514.  
  515.     fSingleSelection = TRUE;
  516. } // TGridView::TGridView
  517.  
  518. //----------------------------------------------------------------------------------------
  519. // TGridView::IGridView: 
  520. //----------------------------------------------------------------------------------------
  521. #pragma segment GVOpen
  522.  
  523. void TGridView::IGridView(TDocument* itsDocument,
  524.                                  // Its document 
  525.                                  TView* itsSuperView,
  526.                                  // Its parent view 
  527.                                  const VPoint& itsLocation,
  528.                                  // Top, Left in parent's coords 
  529.                                  const VPoint& itsSize,
  530.                                  // Ignored for SizeVariable
  531.                                  SizeDeterminer itsHSizeDet,
  532.                                  SizeDeterminer itsVSizeDet,
  533.                                  // Size determiners 
  534.                                  short numOfRows,
  535.                                  // Number of rows initially 
  536.                                  short numOfCols,
  537.                                  // Number of columns initially 
  538.                                  short rowHeight,
  539.                                  // Height of initial rows 
  540.                                  short colWidth,
  541.                                  // Height of initial columns 
  542.                                  Boolean adornRows,
  543.                                  // Adornment for Rows? 
  544.                                  Boolean adornCols,
  545.                                  // Adornment for Columns? 
  546.                                  short rowInset,
  547.                                  // horizontal space between cells 
  548.                                  short colInset,
  549.                                  // vertical space between cells 
  550.                                  Boolean singleSelection)// single cell selection? 
  551.  
  552. {
  553. #if qDebug
  554.     if (!gUGridViewInitialized)
  555.     {
  556.         ProgramBreak("InitUGridView must be called before creating a grid view.");
  557.         Failure(noErr, 0);
  558.     }
  559. #endif
  560.  
  561.     this->IView(itsDocument, itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet);
  562.  
  563.     fAdornRows = adornRows;
  564.     fAdornCols = adornCols;
  565.  
  566.     // Make sure the insets are evenly divided between top/bottom or left/right 
  567.     fRowInset = rowInset;
  568.     if (odd(rowInset))
  569.         ++fRowInset;
  570.  
  571.     fColInset = colInset;
  572.     if (odd(colInset))
  573.         ++fColInset;
  574.  
  575.     FailInfo fi;
  576.     Try(fi)
  577.     {
  578.         TRunArray* aRunArray = new TRunArray;
  579.         aRunArray->IRunArray();
  580.         fColWidths = aRunArray;
  581.         
  582.         aRunArray = new TRunArray;
  583.         aRunArray->IRunArray();
  584.         fRowHeights = aRunArray;
  585.  
  586.         fSelections = MakeNewRgn();                // region to hold current selections 
  587.         fHLRegion = MakeNewRgn();                // region to hold current highlighted cells 
  588.         fTemporarySelections = MakeNewRgn();    // used by SetSelectionRect 
  589.  
  590.         fSingleSelection = singleSelection;
  591.  
  592.         if (numOfCols > 0)
  593.             this->InsColFirst(numOfCols, colWidth);
  594.         if (numOfRows > 0)
  595.             this->InsRowFirst(numOfRows, rowHeight);
  596.  
  597.         this->AddAdorner(gSelectionAdorner, kDrawView, FALSE);// wants DoHighlightSelection 
  598.  
  599.         fi.Success();
  600.     }
  601.     else                                        // Recover
  602.     {
  603.         this->Free();
  604.         fi.ReSignal();
  605.     }
  606.  
  607. } // TGridView::IGridView 
  608.  
  609. //----------------------------------------------------------------------------------------
  610. // TGridView::Clone: 
  611. //----------------------------------------------------------------------------------------
  612. #pragma segment GVNonRes
  613.  
  614. TObject* TGridView::Clone()                // override 
  615. {
  616.     TGridView * aClonedGridView = (TGridView *)(Inherited::Clone());
  617.     VOLATILE(aClonedGridView);
  618.  
  619.     aClonedGridView->fNumOfCols = 0;
  620.     aClonedGridView->fNumOfRows = 0;
  621.     aClonedGridView->fColWidths = NULL;        // For failure handling
  622.     aClonedGridView->fRowHeights = NULL;
  623.     
  624.     // This code is neccessary because MacApp does not support cloning properly
  625.     // It could be replaced with TGridView(inputView).fColWidths.Clone otherwise
  626.  
  627.     FailInfo fi;
  628.     Try(fi)
  629.     {
  630.         TRunArray* aRunArray = new TRunArray;
  631.         aRunArray->IRunArray();
  632.         aClonedGridView->fColWidths = aRunArray;
  633.         
  634.         aRunArray = new TRunArray;
  635.         aRunArray->IRunArray();
  636.         aClonedGridView->fRowHeights = aRunArray;
  637.  
  638.         aClonedGridView->fSelections = MakeNewRgn();// region to hold current selections 
  639.         aClonedGridView->fHLRegion = MakeNewRgn();// region to hold current highlighted cells 
  640.         aClonedGridView->fTemporarySelections = MakeNewRgn();// used by SetSelectionRect 
  641.  
  642.         if (fNumOfCols > 0)
  643.             aClonedGridView->InsColFirst(fNumOfCols, this->GetColWidth(1));
  644.         if (fNumOfRows > 0)
  645.             aClonedGridView->InsRowFirst(fNumOfRows, this->GetRowHeight(1));
  646.  
  647.         fi.Success();
  648.     }
  649.     else                                        // Recover
  650.     {
  651.         aClonedGridView->Free();
  652.         fi.ReSignal();
  653.     }
  654.  
  655.     return aClonedGridView;
  656. } // TGridView::Clone 
  657.  
  658. //----------------------------------------------------------------------------------------
  659. // TGridView::Free: 
  660. //----------------------------------------------------------------------------------------
  661. #pragma segment GVClose
  662.  
  663. void TGridView::Free()                    // override 
  664. {
  665.     // Dispose regions 
  666.     fSelections = DisposeIfRgnHandle(fSelections);
  667.     fHLRegion = DisposeIfRgnHandle(fHLRegion);
  668.     fTemporarySelections = DisposeIfRgnHandle(fTemporarySelections);
  669.  
  670.     fColWidths = (TRunArray *)(FreeIfObject(fColWidths));
  671.     fRowHeights = (TRunArray *)(FreeIfObject(fRowHeights));
  672.  
  673.     Inherited::Free();
  674. } // TGridView::Free 
  675.  
  676. //----------------------------------------------------------------------------------------
  677. // TGridView::GetStandardSignature: 
  678. //----------------------------------------------------------------------------------------
  679. #pragma segment GVWriteResource
  680.  
  681. IDType TGridView::GetStandardSignature()    // override 
  682. {
  683.     return kStdGridView;
  684. } // TGridView::GetStandardSignature 
  685.  
  686. //----------------------------------------------------------------------------------------
  687. // TGridView::ReadFields: 
  688. //----------------------------------------------------------------------------------------
  689. #pragma segment GVReadResource
  690.  
  691. void TGridView::ReadFields(TStream* aStream)// override 
  692. {
  693. #if qDebug
  694.     if (!gUGridViewInitialized)
  695.     {
  696.         ProgramBreak("InitUGridView must be called before creating a grid view.");
  697.         Failure(noErr, 0);
  698.     }
  699. #endif
  700.  
  701.     short numOfCols,
  702.      numOfRows,
  703.      colWidth,
  704.      rowHeight;
  705.  
  706.     Inherited::ReadFields(aStream);
  707.  
  708.     FailInfo fi;
  709.     Try(fi)
  710.     {
  711.         numOfRows = aStream->ReadInteger();
  712.         numOfCols = aStream->ReadInteger();
  713.  
  714.         rowHeight = aStream->ReadInteger();
  715.         colWidth = aStream->ReadInteger();
  716.  
  717.         fRowInset = aStream->ReadInteger();
  718.         fColInset = aStream->ReadInteger();
  719.  
  720.         fAdornRows = aStream->ReadBoolean();
  721.         fAdornCols = aStream->ReadBoolean();
  722.  
  723.         fSingleSelection = aStream->ReadBoolean();
  724.  
  725.         if (odd(fRowInset))
  726.             ++fRowInset;
  727.  
  728.         if (odd(fColInset))
  729.             ++fColInset;
  730.  
  731.         TRunArray* aRunArray = new TRunArray;
  732.         aRunArray->IRunArray();
  733.         fColWidths = aRunArray;
  734.  
  735.         aRunArray = new TRunArray;
  736.         aRunArray->IRunArray();
  737.         fRowHeights = aRunArray;
  738.  
  739.         fSelections = MakeNewRgn();                // region to hold current selections 
  740.         fHLRegion = MakeNewRgn();                // region to hold current highlighted cells 
  741.         fTemporarySelections = MakeNewRgn();    // used by SetSelectionRect 
  742.  
  743.         if (numOfCols > 0)
  744.             this->InsColFirst(numOfCols, colWidth);
  745.         if (numOfRows > 0)
  746.             this->InsRowFirst(numOfRows, rowHeight);
  747.  
  748.         fi.Success();
  749.     }
  750.     else                                        // Recover
  751.         {
  752.         this->Free();
  753.         fi.ReSignal();
  754.     }
  755. } // TGridView::ReadFields 
  756.  
  757. //----------------------------------------------------------------------------------------
  758. // TGridView::WriteFields: 
  759. //----------------------------------------------------------------------------------------
  760. #pragma segment GVWriteResource
  761.  
  762. void TGridView::WriteFields(TStream* aStream)// override 
  763. {
  764.     short rowHeight = 0,
  765.      colWidth = 0;
  766.  
  767.     Inherited::WriteFields(aStream);
  768.  
  769.     if (fNumOfRows > 0)
  770.         rowHeight = this->GetRowHeight(1);
  771.  
  772.     if (fNumOfCols > 0)
  773.         colWidth = this->GetColWidth(1);
  774.  
  775.     aStream->WriteInteger(fNumOfRows);
  776.     aStream->WriteInteger(fNumOfCols);
  777.     aStream->WriteInteger(rowHeight);
  778.     aStream->WriteInteger(colWidth);
  779.     aStream->WriteInteger(fRowInset);
  780.     aStream->WriteInteger(fColInset);
  781.     aStream->WriteBoolean(fAdornRows);
  782.     aStream->WriteBoolean(fAdornCols);
  783.     aStream->WriteBoolean(fSingleSelection);
  784. } // TGridView::WriteFields 
  785.  
  786. //----------------------------------------------------------------------------------------
  787. // TGridView::AdornCol: 
  788. //----------------------------------------------------------------------------------------
  789. #pragma segment GVRes
  790.  
  791. void TGridView::AdornCol(short aCol,
  792.                                 const VRect& area)
  793. {
  794.     CRect qdRect;
  795.  
  796.     PenNormal();
  797.     this->ViewToQDRect(area, qdRect);
  798.  
  799.     MoveTo(qdRect.right, qdRect.top);
  800.     Line(0, qdRect.GetLength(vSel));
  801.     if (aCol == 1)
  802.     {
  803.         MoveTo(qdRect.left, qdRect.top);
  804.         Line(0, qdRect.GetLength(vSel));
  805.     }
  806. } // TGridView::AdornCol 
  807.  
  808. //----------------------------------------------------------------------------------------
  809. // TGridView::AdornRow: 
  810. //----------------------------------------------------------------------------------------
  811. #pragma segment GVRes
  812.  
  813. void TGridView::AdornRow(short aRow,
  814.                                 const VRect& area)
  815. {
  816.     CRect qdRect;
  817.  
  818.     PenNormal();
  819.     this->ViewToQDRect(area, qdRect);
  820.  
  821.     MoveTo(qdRect.left, qdRect.bottom);
  822.     Line(qdRect.GetLength(hSel), 0);
  823.     if (aRow == 1)
  824.     {
  825.         MoveTo(qdRect.left, qdRect.top);
  826.         Line(qdRect.GetLength(hSel), 0);
  827.     }
  828. } // TGridView::AdornRow 
  829.  
  830. //----------------------------------------------------------------------------------------
  831. // TGridView::CalcMinFrame: 
  832. //----------------------------------------------------------------------------------------
  833. #pragma segment GVRes
  834.  
  835. void TGridView::CalcMinFrame(VRect& minFrame)// override 
  836. {
  837.     Inherited::CalcMinFrame(minFrame);
  838.  
  839.     // Set the amount of room needed for that many items 
  840.     minFrame[botRight] = minFrame[topLeft] + VPoint(fColWidths->fTotal, fRowHeights->fTotal);
  841. } // TGridView::CalcMinFrame 
  842.  
  843. //----------------------------------------------------------------------------------------
  844. // TGridView::CanSelectCell: 
  845. //----------------------------------------------------------------------------------------
  846. #pragma segment GVRes
  847.  
  848. Boolean TGridView::CanSelectCell(GridCell aCell)
  849. {
  850.     return ((aCell.h >= 1) && (aCell.v >= 1) && (aCell.h <= fNumOfCols) && (aCell.v <= fNumOfRows));
  851. } // TGridView::CanSelectCell 
  852.  
  853. //----------------------------------------------------------------------------------------
  854. // TGridView::CellToVRect: 
  855. //----------------------------------------------------------------------------------------
  856. #pragma segment GVRes
  857.  
  858. void TGridView::CellToVRect(GridCell aCell,
  859.                                    VRect& aRect)
  860. {
  861.     short width;
  862.     short height;
  863.  
  864.     if ((aCell.h < 1) || (aCell.v < 1) || (aCell.h > fNumOfCols) || (aCell.v > fNumOfRows))
  865.     {
  866. #if qRangeCheck && qDebugMsg
  867.         fprintf(stderr, "aCell.h == %6d fNumOfCols == %6d", aCell.h, fNumOfCols);
  868.         fprintf(stderr, "aCell.v == %6d fNumOfRows == %6d", aCell.v, fNumOfRows);
  869.         ProgramBreak("Range Check in CellToVRect");
  870. #endif
  871.  
  872.         aRect = gZeroVRect;
  873.     }
  874.     else                                        // all the params look OK 
  875.     {
  876.         width = fColWidths->GetValue(aCell.h);
  877.         if (fColWidths->fNoOfChunks == 1)
  878.             aRect.left = width * (aCell.h - 1);
  879.         else
  880.             aRect.left = fColWidths->SumValues(1, aCell.h - 1);
  881.         aRect.right = aRect.left + width;
  882.  
  883.         height = fRowHeights->GetValue(aCell.v);
  884.         if (fRowHeights->fNoOfChunks == 1)
  885.             aRect.top = height * (aCell.v - 1);
  886.         else
  887.             aRect.top = fRowHeights->SumValues(1, aCell.v - 1);
  888.         aRect.bottom = aRect.top + height;
  889.     }
  890. } // TGridView::CellToVRect 
  891.  
  892. //----------------------------------------------------------------------------------------
  893. // TGridView::ColToVRect: 
  894. //----------------------------------------------------------------------------------------
  895. #pragma segment GVRes
  896.  
  897. void TGridView::ColToVRect(short aCol,
  898.                                   short numOfCols,
  899.                                   VRect& aRect)
  900. {
  901.     long width;
  902.     long leftEdge;
  903.  
  904.     if ((aCol < 1) || (numOfCols < 1) || (aCol + numOfCols - 1 > fNumOfCols))
  905.     {
  906. #if qDebugMsg && qRangeCheck
  907.         fprintf(stderr, "fNumOfCols == %1d aCol == %1d", fNumOfCols, aCol);
  908.         ProgramBreak("Range Check in ColToVRect");
  909. #endif
  910.  
  911.         aRect = gZeroVRect;
  912.     }
  913.     else                                        // all the params look OK 
  914.     {
  915.         if (fColWidths->fNoOfChunks == 1)        // only one column width 
  916.         {
  917.             width = this->GetColWidth(1);
  918.             leftEdge = width * (aCol - 1);
  919.             width *= numOfCols;
  920.         }
  921.         else
  922.         {
  923.             leftEdge = fColWidths->SumValues(1, aCol - 1);
  924.             width = fColWidths->SumValues(aCol, numOfCols);
  925.         }
  926.  
  927.         aRect = VRect(leftEdge, 0, leftEdge + width, fRowHeights->fTotal);
  928.     }
  929. } // TGridView::ColToVRect 
  930.  
  931. //----------------------------------------------------------------------------------------
  932. // TGridView::AddStrip: 
  933. //----------------------------------------------------------------------------------------
  934. #pragma segment GVRes
  935.  
  936. void TGridView::AddStrip(RgnHandle thePixels,
  937.                                 VHSelect direction,
  938.                                 short& startOfStrip,
  939.                                 short endOfStrip,
  940.                                 CRect& stripRect,
  941.                                 short row,
  942.                                 short col,
  943.                                 VRect& pixels,
  944.                                 VRect& previousPixels,
  945.                                 CRect& prevStripRect)
  946. {
  947.     CRect qdRect;
  948.  
  949.     if (direction == vSel)
  950.         stripRect = CRect(col, startOfStrip, col, endOfStrip);
  951.     else
  952.         stripRect = CRect(startOfStrip, row, endOfStrip, row);
  953.  
  954. #if qDebugMsg
  955.     if (gIntenseDebugging)
  956.     {
  957.         fprintf(stderr, "Adding cells = %s\n", (char*)stripRect);
  958.     }
  959. #endif
  960.  
  961.     pixels = previousPixels;
  962.  
  963.     if (stripRect.top != prevStripRect.top)
  964.         pixels.top = this->fRowHeights->SumValues(1, stripRect.top - 1);
  965.     if (stripRect.bottom != prevStripRect.bottom)
  966.     {
  967.         if (stripRect.bottom == stripRect.top)
  968.             pixels.bottom = pixels.top + this->fRowHeights->GetValue(stripRect.bottom);
  969.         else
  970.             pixels.bottom = this->fRowHeights->SumValues(1, stripRect.bottom);
  971.     }
  972.     if (stripRect.left != prevStripRect.left)
  973.         pixels.left = this->fColWidths->SumValues(1, stripRect.left - 1);
  974.     if (stripRect.right != prevStripRect.right)
  975.     {
  976.         if (stripRect.right == stripRect.left)
  977.             pixels.right = pixels.left + this->fColWidths->GetValue(stripRect.right);
  978.         else
  979.             pixels.right = this->fColWidths->SumValues(1, stripRect.right);
  980.     }
  981.  
  982.     previousPixels = pixels;
  983.  
  984.     CTemporaryRegion tempRgn;
  985.  
  986.     SetEmptyRgn(tempRgn);
  987.     this->ViewToQDRect(pixels, qdRect);
  988.     RectRgn(tempRgn, qdRect);
  989.     UnionRgn(tempRgn, thePixels, thePixels);
  990.  
  991.     prevStripRect = stripRect;
  992.     startOfStrip = 0;
  993. } // TGridView::AddStrip 
  994.  
  995.  
  996. //----------------------------------------------------------------------------------------
  997. // TGridView::CellsToPixels: 
  998. //----------------------------------------------------------------------------------------
  999. void TGridView::CellsToPixels(RgnHandle theCells,
  1000.                                      RgnHandle thePixels)
  1001. {
  1002.     CRect stripRect;
  1003.     GridCell aCell;
  1004.     short row,
  1005.      col;
  1006.     VRect pixels;
  1007.     VRect previousPixels;
  1008.     short startOfStrip;
  1009.  
  1010.     SetEmptyRgn(thePixels);
  1011.  
  1012.     if (!EmptyRgn(theCells) && this->Focus())
  1013.     {
  1014.         if ((*theCells)->rgnSize == 10)            // the region is a rectangle 
  1015.         {
  1016.             CRect cellBounds = (**theCells).rgnBBox;
  1017.             pixels = VRect(fColWidths->SumValues(1, cellBounds.left - 1), fRowHeights->SumValues(1, cellBounds.top - 1), fColWidths->SumValues(1, cellBounds.right - 1), fRowHeights->SumValues(1, cellBounds.bottom - 1));
  1018.             this->ViewToQDRect(pixels, (CRect &) (*thePixels)->rgnBBox);
  1019.         }
  1020.         else
  1021.         {
  1022.             // Reduce the cells to only those that are visible 
  1023.             CRect visibleCells;
  1024.             VRect visibleVRect;
  1025.             this->GetVisibleRect(visibleVRect);
  1026.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  1027.             GridCell temp = this->VPointToLastCell(visibleVRect[topLeft]);
  1028.             visibleCells[topLeft] = temp;
  1029.             // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
  1030.             temp = this->VPointToLastCell(visibleVRect[botRight]);
  1031.             visibleCells[botRight] = temp;
  1032.             SetRectRgn(pVisibleCells, visibleCells.left, visibleCells.top, visibleCells.right + 1, visibleCells.bottom + 1);
  1033.             SectRgn(theCells, pVisibleCells, pVisibleCells);
  1034.             CRect cellBounds = (**pVisibleCells).rgnBBox;
  1035.  
  1036.             CRect prevStripRect = gZeroRect;
  1037.             VHSelect direction = LongerSide(cellBounds);
  1038.             if (direction == vSel)
  1039.             {
  1040.                 for (col = cellBounds.left; col < cellBounds.right; ++col)
  1041.                 {
  1042.                     aCell.h = col;
  1043.                     startOfStrip = 0;
  1044.                     for (row = cellBounds.top; row < cellBounds.bottom; ++row)
  1045.                     {
  1046.                         aCell.v = row;
  1047.                         if (PtInRgn(aCell, pVisibleCells))
  1048.                         {
  1049.                             if (startOfStrip == 0)
  1050.                                 startOfStrip = row;
  1051.                         }
  1052.                         else if (startOfStrip > 0)
  1053.                             this->AddStrip(thePixels, direction, startOfStrip, row - 1, stripRect, row, col, pixels, previousPixels, prevStripRect);
  1054.                     }
  1055.                     if (startOfStrip > 0)
  1056.                         this->AddStrip(thePixels, direction, startOfStrip, cellBounds.bottom - 1, stripRect, row, col, pixels, previousPixels, prevStripRect);
  1057.                 }
  1058.             }
  1059.             else
  1060.             {
  1061.                 for (row = cellBounds.top; row < cellBounds.bottom; ++row)
  1062.                 {
  1063.                     aCell.v = row;
  1064.                     startOfStrip = 0;
  1065.                     for (col = cellBounds.left; col < cellBounds.right; ++col)
  1066.                     {
  1067.                         aCell.h = col;
  1068.                         if (PtInRgn(aCell, pVisibleCells))
  1069.                         {
  1070.                             if (startOfStrip == 0)
  1071.                                 startOfStrip = col;
  1072.                         }
  1073.                         else if (startOfStrip > 0)
  1074.                             this->AddStrip(thePixels, direction, startOfStrip, col - 1, stripRect, row, col, pixels, previousPixels, prevStripRect);
  1075.                     }
  1076.                     if (startOfStrip > 0)
  1077.                         this->AddStrip(thePixels, direction, startOfStrip, cellBounds.right - 1, stripRect, row, col, pixels, previousPixels, prevStripRect);
  1078.                 }
  1079.             }
  1080.         }
  1081.     }
  1082. } // TGridView::CellsToPixels 
  1083.  
  1084. //----------------------------------------------------------------------------------------
  1085. // TGridView::DoHighlightSelection: 
  1086. //----------------------------------------------------------------------------------------
  1087. #pragma segment GVRes
  1088.  
  1089. void TGridView::DoHighlightSelection(HLState fromHL,
  1090.                                             HLState toHL)// override 
  1091. {
  1092.     if (!EmptyRgn(fHLRegion))
  1093.         this->HighlightCells(fHLRegion, fromHL, toHL);
  1094. } // TGridView::DoHighlightSelection 
  1095.  
  1096. //----------------------------------------------------------------------------------------
  1097. // TGridView::HighlightCells: 
  1098. //----------------------------------------------------------------------------------------
  1099. #pragma segment GVRes
  1100.  
  1101. void TGridView::HighlightCells(RgnHandle theCells,
  1102.                                       HLState fromHL,
  1103.                                       HLState toHL)
  1104. {
  1105.     if ((fromHL != toHL) && this->Focus())
  1106.     {
  1107.         this->CellsToPixels(theCells, pPixelsToHighlight);
  1108.         switch (fromHL + toHL)
  1109.         {
  1110.             case hlOffDim:
  1111.                 PenNormal();
  1112.                 PenMode(patXor);
  1113.                 UseSelectionColor();
  1114.                 FrameRgn(pPixelsToHighlight);
  1115.                 break;
  1116.             case hlOnDim:
  1117.                 {
  1118.                     CTemporaryRegion innerRgn;
  1119.                     CopyRgn(pPixelsToHighlight, innerRgn);
  1120.                     InsetRgn(innerRgn, 1, 1);
  1121.                     PenNormal();
  1122.                     UseSelectionColor();
  1123.                     InvertRgn(innerRgn);
  1124.                 }
  1125.                 break;
  1126.             case hlOffOn:
  1127.                 PenNormal();
  1128.                 UseSelectionColor();
  1129.                 InvertRgn(pPixelsToHighlight);
  1130.                 break;
  1131.         }
  1132.     }
  1133. }                                                // TGridView::HighlightCells 
  1134.  
  1135. //----------------------------------------------------------------------------------------
  1136. // TGridView::DoMenuCommand: 
  1137. //----------------------------------------------------------------------------------------
  1138. #pragma segment GVRes
  1139.  
  1140. void TGridView::DoMenuCommand(CommandNumber aCommandNumber)
  1141. {
  1142.     switch (aCommandNumber)
  1143.     {
  1144.         case cSelectAll:
  1145.             {
  1146.                 CCellIterator iter(this);
  1147.  
  1148.                 for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
  1149.                 {
  1150.                     if (this->CanSelectCell(aCell))
  1151.                         this->SelectCell(aCell, kExtend, kHighlight, kSelect);
  1152.                 }
  1153.                 break;
  1154.             }
  1155.  
  1156.         default:
  1157.             Inherited::DoMenuCommand(aCommandNumber);
  1158.             break;
  1159.     }
  1160. }                                                // TGridView::DoMenuCommand 
  1161.  
  1162. //----------------------------------------------------------------------------------------
  1163. // TGridView::DoMouseCommand: 
  1164. //----------------------------------------------------------------------------------------
  1165. #pragma segment GVRes
  1166.  
  1167. void TGridView::DoMouseCommand(VPoint& theMouse,
  1168.                                       TToolboxEvent* event,
  1169.                                       CPoint)    // override 
  1170. {
  1171.     GridCell aCell;
  1172.  
  1173.     if ((this->IdentifyPoint(theMouse, aCell) != badChoice)  && this->CanSelectCell(aCell))
  1174.     {
  1175.         TCellSelectCommand * aCellSelectCommand = new TCellSelectCommand;
  1176.         aCellSelectCommand->ICellSelectCommand(this, theMouse, event->IsShiftKeyPressed(), event->IsCommandKeyPressed());
  1177.         this->PostCommand(aCellSelectCommand);
  1178.     }
  1179. } // TGridView::DoMouseCommand 
  1180.  
  1181. //----------------------------------------------------------------------------------------
  1182. // TGridView::Draw: 
  1183. //----------------------------------------------------------------------------------------
  1184. #pragma segment GVRes
  1185.  
  1186. void TGridView::Draw(const VRect& area)    // override 
  1187. {
  1188.     VRect aRect;
  1189.     VRect bRect;
  1190.     register short i;
  1191.     GridCell startCell;
  1192.     GridCell stopCell;
  1193.     VRect viewArea(area);
  1194.     GridCell startCellToDraw;
  1195.     VRect cellsArea;
  1196.     VRect localArea(area);                        // use localArea (because area is const)
  1197.  
  1198.     if ((fNumOfRows > 0) && (fNumOfCols > 0))
  1199.     {
  1200.         // make sure we have something to draw 
  1201.  
  1202.         startCell = this->VPointToLastCell(viewArea[topLeft]);
  1203.         stopCell = this->VPointToLastCell(viewArea[botRight]);
  1204.  
  1205.         this->CellToVRect(startCell, aRect);
  1206.         this->CellToVRect(stopCell, bRect);
  1207.         bRect[topLeft] = aRect[topLeft];
  1208.         localArea = bRect;
  1209.  
  1210.         startCellToDraw = startCell;
  1211.         cellsArea = localArea;
  1212.         if (viewArea.top >= aRect.bottom - (fRowInset / 2))//((fRowInset) >> 1)
  1213.         {
  1214.             ++startCellToDraw.v;
  1215.             cellsArea.top += aRect.GetLength(vSel);
  1216.         }
  1217.  
  1218.         this->DrawRangeOfCells(startCellToDraw, stopCell, cellsArea);
  1219.  
  1220.         if (fAdornCols)
  1221.         {
  1222.             short colWidth = 0;
  1223.             aRect = localArea;
  1224.  
  1225.             register Boolean constantWidth = fColWidths->fNoOfChunks == 1;
  1226.             if (constantWidth)                    // only one width 
  1227.                 colWidth = this->GetColWidth(1);
  1228.  
  1229.             for (i = startCell.h; i <= stopCell.h; ++i)
  1230.             {
  1231.                 if (constantWidth)
  1232.                     aRect.right = aRect.left + colWidth;
  1233.                 else
  1234.                     aRect.right = aRect.left + this->GetColWidth(i);
  1235.  
  1236.                 this->AdornCol(i, aRect);
  1237.                 aRect.left = aRect.right;
  1238.             }
  1239.         }
  1240.  
  1241.         if (fAdornRows)
  1242.         {
  1243.             short rowHeight = 0;
  1244.             aRect = localArea;
  1245.  
  1246.             register Boolean constantHeight = fRowHeights->fNoOfChunks == 1;
  1247.             if (constantHeight)                    // only one height 
  1248.                 rowHeight = this->GetRowHeight(1);
  1249.  
  1250.             for (i = startCell.v; i <= stopCell.v; ++i)
  1251.             {
  1252.                 if (constantHeight)
  1253.                     aRect.bottom = aRect.top + rowHeight;
  1254.                 else
  1255.                     aRect.bottom = aRect.top + this->GetRowHeight(i);
  1256.  
  1257.                 this->AdornRow(i, aRect);
  1258.                 aRect.top = aRect.bottom;
  1259.             }
  1260.         }
  1261.     }
  1262.  
  1263.     Inherited::Draw(localArea);
  1264. } // TGridView::Draw 
  1265.  
  1266. //----------------------------------------------------------------------------------------
  1267. // TGridView::DrawRangeOfCells: 
  1268. //----------------------------------------------------------------------------------------
  1269. #pragma segment GVRes
  1270.  
  1271. void TGridView::DrawRangeOfCells(GridCell startCell,
  1272.                                         GridCell stopCell,
  1273.                                         const VRect& aRect)
  1274. {
  1275.     VCoordinate colWidth;
  1276.     VCoordinate rowHeight;
  1277.  
  1278.     VRect localVRect(aRect);                    // added because argument is const
  1279.     localVRect.left += fColInset / 2;
  1280.     localVRect.top += fRowInset / 2;
  1281.  
  1282.     VCoordinate left = localVRect.left;            // save it for each iteration of for loop
  1283.  
  1284.     if (fColWidths->fNoOfChunks == 1)            // only one width 
  1285.         colWidth = this->GetColWidth(1);
  1286.     if (fRowHeights->fNoOfChunks == 1)            // only one height 
  1287.         rowHeight = this->GetRowHeight(1);
  1288.  
  1289.     CTemporaryRegion drawableRegion;
  1290.     this->GetDrawableRegion(drawableRegion);
  1291.  
  1292.     for (short j = startCell.v; j <= stopCell.v; ++j)
  1293.     {
  1294.         localVRect.bottom = localVRect.top - fRowInset;
  1295.         if (fRowHeights->fNoOfChunks == 1)        // only one height 
  1296.             localVRect.bottom += rowHeight;
  1297.         else
  1298.             localVRect.bottom += this->GetRowHeight(j);
  1299.  
  1300.         localVRect.left = left;                    // start back at the left for the next row 
  1301.  
  1302.         for (short i = startCell.h; i <= stopCell.h; ++i)
  1303.         {
  1304.             localVRect.right = localVRect.left - fColInset;
  1305.             if (fColWidths->fNoOfChunks == 1)    // only one height 
  1306.                 localVRect.right += colWidth;
  1307.             else
  1308.                 localVRect.right += this->GetColWidth(i);
  1309.  
  1310.             // check if the rect is drawable
  1311.             CRect qdRect;
  1312.             this->ViewToQDRect(localVRect, qdRect);
  1313.             if (RectInRgn(qdRect, drawableRegion))
  1314.                 this->DrawCell(GridCell(i, j), localVRect);
  1315.  
  1316.             localVRect.left = localVRect.right + fColInset;
  1317.         }
  1318.         localVRect.top = localVRect.bottom + fRowInset;
  1319.     }
  1320. } // TGridView::DrawRangeOfCells 
  1321.  
  1322. //----------------------------------------------------------------------------------------
  1323. // TGridView::DrawCell: 
  1324. //----------------------------------------------------------------------------------------
  1325. #pragma segment GVRes
  1326.  
  1327. void TGridView::DrawCell(GridCell        /* aCell */,
  1328.                                 const VRect&    /* aRect */)
  1329. {
  1330. } // TGridView::DrawCell 
  1331.  
  1332. //----------------------------------------------------------------------------------------
  1333. // TGridView::DelColAt: 
  1334. //----------------------------------------------------------------------------------------
  1335. #pragma segment GVNonRes
  1336.  
  1337. void TGridView::DelColAt(short aCol,
  1338.                                 short numOfCols)
  1339. {
  1340.     VRect aVRect;
  1341.  
  1342.     if ((aCol < 1) || (numOfCols < 1) || (aCol + numOfCols - 1 > fNumOfCols))
  1343.     {
  1344.         if (numOfCols != 0)
  1345.         {
  1346. #if qDebugMsg
  1347.             fprintf(stderr, "fNumOfCols == %1d   aCol == %1d\n", fNumOfCols, aCol);
  1348.             ProgramBreak("Range Check in DelColAt");
  1349.             return;
  1350. #endif
  1351.  
  1352.         }
  1353.     }
  1354.     else
  1355.     {
  1356.         long maxCol = Max(1, aCol);
  1357.         this->ColToVRect((short)maxCol, (short)Max(1, fNumOfCols - aCol + 1), aVRect);//!!! cast
  1358.         fColWidths->DeleteItems(aCol, numOfCols);
  1359.         fNumOfCols -= numOfCols;
  1360.         this->AdjustFrame();
  1361.         this->InvalidateVRect(aVRect);
  1362.     }
  1363. } // TGridView::DelColAt 
  1364.  
  1365. //----------------------------------------------------------------------------------------
  1366. // TGridView::DelRowAt: 
  1367. //----------------------------------------------------------------------------------------
  1368. #pragma segment GVNonRes
  1369.  
  1370. void TGridView::DelRowAt(short aRow,
  1371.                                 short numOfRows)
  1372. {
  1373.     if ((aRow < 1) || (numOfRows < 1) || (aRow + numOfRows - 1 > fNumOfRows))
  1374.     {
  1375.         if (numOfRows != 0)
  1376.         {
  1377. #if qDebugMsg
  1378.             fprintf(stderr, "fNumOfRows == %1d  aRow == %1d\n", fNumOfRows, aRow);
  1379.             ProgramBreak("Range Check in DelRowAt");
  1380.             return;
  1381. #endif
  1382.         }
  1383.     }
  1384.     else
  1385.     {
  1386.         long maxRow = Max(1, aRow);
  1387.         VRect aVRect;
  1388.         this->RowToVRect((short)maxRow, (short)Max(1, fNumOfRows - aRow + 1), aVRect);//!!! cast
  1389.         fRowHeights->DeleteItems(aRow, numOfRows);
  1390.         fNumOfRows -= numOfRows;
  1391.         this->AdjustFrame();
  1392.         this->InvalidateVRect(aVRect);
  1393.     }
  1394. } // TGridView::DelRowAt 
  1395.  
  1396. //----------------------------------------------------------------------------------------
  1397. // TGridView::DelColFirst: 
  1398. //----------------------------------------------------------------------------------------
  1399. #pragma segment GVNonRes
  1400.  
  1401. void TGridView::DelColFirst(short numOfCols)
  1402. {
  1403.     this->DelColAt(1, numOfCols);
  1404. } // TGridView::DelColFirst 
  1405.  
  1406. //----------------------------------------------------------------------------------------
  1407. // TGridView::DelRowFirst: 
  1408. //----------------------------------------------------------------------------------------
  1409. #pragma segment GVNonRes
  1410.  
  1411. void TGridView::DelRowFirst(short numOfRows)
  1412. {
  1413.     this->DelRowAt(1, numOfRows);
  1414. } // TGridView::DelRowFirst 
  1415.  
  1416. //----------------------------------------------------------------------------------------
  1417. // TGridView::DelColLast: 
  1418. //----------------------------------------------------------------------------------------
  1419. #pragma segment GVNonRes
  1420.  
  1421. void TGridView::DelColLast(short numOfCols)
  1422. {
  1423.     this->DelColAt(fNumOfCols - numOfCols + 1, numOfCols);
  1424. } // TGridView::DelColLast 
  1425.  
  1426. //----------------------------------------------------------------------------------------
  1427. // TGridView::DelRowLast: 
  1428. //----------------------------------------------------------------------------------------
  1429. #pragma segment GVNonRes
  1430.  
  1431. void TGridView::DelRowLast(short numOfRows)
  1432. {
  1433.     this->DelRowAt(fNumOfRows - numOfRows + 1, numOfRows);
  1434. } // TGridView::DelRowLast 
  1435.  
  1436. //----------------------------------------------------------------------------------------
  1437. // TGridView::FirstSelectedCell: 
  1438. //----------------------------------------------------------------------------------------
  1439. #pragma segment GVRes
  1440.  
  1441. GridCell TGridView::FirstSelectedCell()
  1442. {
  1443.     CRect bounds;
  1444.     GridCell aCell;
  1445.     GridCell result;
  1446.  
  1447.     result = gZeroPt;
  1448.     if (this->IsAnyCellSelected())
  1449.     {
  1450.         bounds = (*fSelections)->rgnBBox;
  1451.         if ((**fSelections).rgnSize == 10)        // whole rectangle 
  1452.             result = bounds[topLeft];
  1453.         else
  1454.             for (short i = bounds.top; i <= bounds.bottom - 1; ++i)
  1455.         {
  1456.             aCell.v = i;
  1457.             for (short j = bounds.left; j <= bounds.right - 1; ++j)
  1458.             {
  1459.                 aCell.h = j;
  1460.                 if (PtInRgn(aCell, fSelections))
  1461.                 {
  1462.                     result = aCell;
  1463.                     return result;
  1464.                 }
  1465.             }
  1466.         }
  1467.     }
  1468.     return result;
  1469. } // TGridView::FirstSelectedCell 
  1470.  
  1471. //----------------------------------------------------------------------------------------
  1472. // TGridView::GetColWidth: 
  1473. //----------------------------------------------------------------------------------------
  1474. #pragma segment GVRes
  1475.  
  1476. short TGridView::GetColWidth(short aCol)
  1477. {
  1478.     if ((aCol < 1) || (aCol > fNumOfCols))
  1479.     {
  1480. #if qRangeCheck && qDebugMsg
  1481.         fprintf(stderr, "fNumOfCols == &1d  aCol == %1d\n", fNumOfCols, aCol);
  1482.         ProgramBreak("Range Check in GetColWidth");
  1483. #endif
  1484.  
  1485.         return 0;
  1486.     }
  1487.     else
  1488.         return fColWidths->GetValue(aCol);
  1489. } // TGridView::GetColWidth 
  1490.  
  1491. //----------------------------------------------------------------------------------------
  1492. // TGridView::GetRowHeight: 
  1493. //----------------------------------------------------------------------------------------
  1494. #pragma segment GVRes
  1495.  
  1496. short TGridView::GetRowHeight(short aRow)
  1497. {
  1498.     if ((aRow < 1) || (aRow > fNumOfRows))
  1499.     {
  1500. #if qRangeCheck && qDebugMsg
  1501.         fprintf(stderr, "fNumOfRows == &1d  aRow == %1d\n", fNumOfRows, aRow);
  1502.         ProgramBreak("Range Check in GetRowHeight");
  1503. #endif
  1504.  
  1505.         return 0;
  1506.     }
  1507.     else
  1508.         return fRowHeights->GetValue(aRow);
  1509. } // TGridView::GetRowHeight 
  1510.  
  1511. //----------------------------------------------------------------------------------------
  1512. // TGridView::InvalidateCell: 
  1513. //----------------------------------------------------------------------------------------
  1514. #pragma segment GVRes
  1515.  
  1516. void TGridView::InvalidateCell(GridCell aCell)
  1517. {
  1518.     VRect aVRect;
  1519.  
  1520.     this->CellToVRect(aCell, aVRect);
  1521.     this->InvalidateVRect(aVRect);
  1522. } // TGridView::InvalidateCell 
  1523.  
  1524. //----------------------------------------------------------------------------------------
  1525. // TGridView::InvalidateSelection: 
  1526. //----------------------------------------------------------------------------------------
  1527. #pragma segment GVRes
  1528.  
  1529. void TGridView::InvalidateSelection()
  1530. {
  1531.     if (this->Focus())
  1532.     {
  1533.         this->CellsToPixels(fSelections, pInvalidateRgn);
  1534.         this->InvalidateRegion(pInvalidateRgn);
  1535.     }
  1536. } // TGridView::InvalidateSelection 
  1537.  
  1538. //----------------------------------------------------------------------------------------
  1539. // TGridView::IdentifyPoint: 
  1540. //----------------------------------------------------------------------------------------
  1541. #pragma segment GVRes
  1542.  
  1543. GridViewPart TGridView::IdentifyPoint(const VPoint& thePoint,
  1544.                                              GridCell& aCell)
  1545. {
  1546.     GridViewPart aGridViewPart = badChoice;    // default value
  1547.  
  1548.     aCell = this->VPointToCell(thePoint);
  1549.  
  1550.     if (aCell != gZeroPt)
  1551.     {
  1552.         VRect aVRect;
  1553.         this->CellToVRect(aCell, aVRect);
  1554.         aVRect.Inset(VPoint(fColInset / 2, fRowInset / 2));
  1555.         aGridViewPart = inCell;
  1556.  
  1557.         if (fColInset > 0)
  1558.         {
  1559.             if (thePoint.h < aVRect.left)
  1560.             {
  1561.                 aGridViewPart = inColumn;        // To the left of the cell 
  1562.             }
  1563.             else if (thePoint.h >= aVRect.right)    // Remember PtInRgn will report a CPoint
  1564.                                                 // as in a region only if the pixel to the
  1565.                                                 // right and below the CPoint is contained
  1566.                                                 // in the region.
  1567.             {
  1568.                 aGridViewPart = inColumn;        // To the right of the cell 
  1569.                 ++aCell.h;
  1570.                 if (aCell.h > fNumOfCols)
  1571.                     aGridViewPart = badChoice;
  1572.             }
  1573.         }
  1574.  
  1575.         if (fRowInset > 0)
  1576.         {
  1577.             if (thePoint.v < aVRect.top)
  1578.             {
  1579.                 if (aGridViewPart == inColumn)
  1580.                     aGridViewPart = inVertex;    // Click on both 
  1581.                 else
  1582.                     aGridViewPart = inRow;        // Above the cell 
  1583.             }
  1584.             else if (thePoint.v >= aVRect.bottom)// Remember PtInRgn will report a CPoint
  1585.                                                 // as in a region only if the pixel to the
  1586.                                                 // right and below the CPoint is contained
  1587.                                                 // in the region.
  1588.             {
  1589.                 if (aGridViewPart == inColumn)
  1590.                     aGridViewPart = inVertex;    // Click on both 
  1591.                 else
  1592.                     aGridViewPart = inRow;        // Above the cell 
  1593.                 ++aCell.v;
  1594.                 if (aCell.v > fNumOfRows)
  1595.                     aGridViewPart = badChoice;
  1596.             }
  1597.         }
  1598.     }
  1599.     return aGridViewPart;
  1600. } // TGridView::IdentifyPoint 
  1601.  
  1602. //----------------------------------------------------------------------------------------
  1603. // TGridView::InsColBefore: 
  1604. //----------------------------------------------------------------------------------------
  1605. #pragma segment GVRes
  1606.  
  1607. void TGridView::InsColBefore(short aCol,
  1608.                                     short numOfCols,
  1609.                                     short aWidth)
  1610. {
  1611.     if ((aCol < 1) || (numOfCols < 1))
  1612.     {
  1613.         if (numOfCols != 0)
  1614.         {
  1615. #if qDebugMsg && qRangeCheck
  1616.             fprintf(stderr, "fNumOfCols == %1d aCol == %1d", fNumOfCols, aCol);
  1617.             ProgramBreak("Range Check in InsColBefore");
  1618. #endif
  1619.  
  1620.         }
  1621.     }
  1622.     else
  1623.     {
  1624.         fColWidths->InsertItems(aCol, numOfCols, aWidth);
  1625.         fNumOfCols += numOfCols;
  1626.         this->AdjustFrame();
  1627.         long maxCol = Max(1, aCol);
  1628.         VRect aVRect;
  1629.         this->ColToVRect((short)maxCol, (short)Max(1, fNumOfCols - aCol + 1), aVRect);
  1630.         this->InvalidateVRect(aVRect);
  1631.     }
  1632. } // TGridView::InsColBefore 
  1633.  
  1634. //----------------------------------------------------------------------------------------
  1635. // TGridView::InsRowBefore: 
  1636. //----------------------------------------------------------------------------------------
  1637. #pragma segment GVRes
  1638.  
  1639. void TGridView::InsRowBefore(short aRow,
  1640.                                     short numOfRows,
  1641.                                     short aHeight)
  1642. {
  1643.     if ((aRow < 1) || (numOfRows < 1))
  1644.     {
  1645.         if (numOfRows != 0)
  1646.         {
  1647. #if qDebugMsg && qRangeCheck
  1648.             fprintf(stderr, "fNumOfRows == %1d aRow == %1d", fNumOfRows, aRow);
  1649.             ProgramBreak("Range Check in InsRowBefore");
  1650. #endif
  1651.  
  1652.         }
  1653.     }
  1654.     else
  1655.     {
  1656.         fRowHeights->InsertItems(aRow, numOfRows, aHeight);
  1657.         fNumOfRows += numOfRows;
  1658.         this->AdjustFrame();
  1659.         long maxRow = Max(1, aRow);
  1660.         VRect aVRect;
  1661.         this->RowToVRect((short)maxRow, (short)Max(1, fNumOfRows - aRow + 1), aVRect);//!!! Cast
  1662.         this->InvalidateVRect(aVRect);
  1663.     }
  1664. } // TGridView::InsRowBefore 
  1665.  
  1666. //----------------------------------------------------------------------------------------
  1667. // TGridView::InsColLast: 
  1668. //----------------------------------------------------------------------------------------
  1669. #pragma segment GVRes
  1670.  
  1671. void TGridView::InsColLast(short numOfCols,
  1672.                                   short aWidth)
  1673. {
  1674.     this->InsColBefore(fNumOfCols + 1, numOfCols, aWidth);
  1675. } // TGridView::InsColLast 
  1676.  
  1677. //----------------------------------------------------------------------------------------
  1678. // TGridView::InsRowLast: 
  1679. //----------------------------------------------------------------------------------------
  1680. #pragma segment GVRes
  1681.  
  1682. void TGridView::InsRowLast(short numOfRows,
  1683.                                   short aHeight)
  1684. {
  1685.     this->InsRowBefore(fNumOfRows + 1, numOfRows, aHeight);
  1686. } // TGridView::InsRowLast 
  1687.  
  1688. //----------------------------------------------------------------------------------------
  1689. // TGridView::InsColFirst: 
  1690. //----------------------------------------------------------------------------------------
  1691. #pragma segment GVRes
  1692.  
  1693. void TGridView::InsColFirst(short numOfCols,
  1694.                                    short aWidth)
  1695. {
  1696.     this->InsColBefore(1, numOfCols, aWidth);
  1697. } // TGridView::InsColFirst 
  1698.  
  1699. //----------------------------------------------------------------------------------------
  1700. // TGridView::InsRowFirst: 
  1701. //----------------------------------------------------------------------------------------
  1702. #pragma segment GVRes
  1703.  
  1704. void TGridView::InsRowFirst(short numOfRows,
  1705.                                    short aHeight)
  1706. {
  1707.     this->InsRowBefore(1, numOfRows, aHeight);
  1708. } // TGridView::InsRowFirst 
  1709.  
  1710. //----------------------------------------------------------------------------------------
  1711. // TGridView::IsCellSelected: 
  1712. //----------------------------------------------------------------------------------------
  1713. #pragma segment GVRes
  1714.  
  1715. Boolean TGridView::IsCellSelected(GridCell aCell)
  1716. {
  1717.     return PtInRgn(aCell, fSelections);
  1718. } // TGridView::IsCellSelected 
  1719.  
  1720. //----------------------------------------------------------------------------------------
  1721. // TGridView::IsAnyCellSelected: 
  1722. //----------------------------------------------------------------------------------------
  1723. #pragma segment GVRes
  1724.  
  1725. Boolean TGridView::IsAnyCellSelected()
  1726. {
  1727.     return !EmptyRgn(fSelections);
  1728. } // TGridView::IsAnyCellSelected 
  1729.  
  1730. //----------------------------------------------------------------------------------------
  1731. // TGridView::LastSelectedCell: 
  1732. //----------------------------------------------------------------------------------------
  1733. #pragma segment GVRes
  1734.  
  1735. GridCell TGridView::LastSelectedCell()
  1736. {
  1737.     CRect bounds;
  1738.     GridCell aCell;
  1739.     GridCell result;
  1740.  
  1741.     result = gZeroPt;
  1742.     if (this->IsAnyCellSelected())
  1743.     {
  1744.         bounds = (**fSelections).rgnBBox;
  1745.         if ((**fSelections).rgnSize == 10)        // whole rectangle 
  1746.         {
  1747.             aCell.h = bounds.right - 1;
  1748.             aCell.v = bounds.bottom - 1;
  1749.             result = aCell;
  1750.         }
  1751.         else
  1752.             for (short i = bounds.bottom - 1; i >= bounds.top; i--)
  1753.         {
  1754.             aCell.v = i;
  1755.             for (short j = bounds.right - 1; j >= bounds.left; j--)
  1756.             {
  1757.                 aCell.h = j;
  1758.                 if (PtInRgn(aCell, fSelections))
  1759.                 {
  1760.                     result = aCell;
  1761.                     return result;
  1762.                 }
  1763.             }
  1764.         }
  1765.     }
  1766.     return result;
  1767. } // TGridView::LastSelectedCell 
  1768.  
  1769. //----------------------------------------------------------------------------------------
  1770. // TGridView::RowToVRect: 
  1771. //----------------------------------------------------------------------------------------
  1772. #pragma segment GVRes
  1773.  
  1774. void TGridView::RowToVRect(short aRow,
  1775.                                   short numOfRows,
  1776.                                   VRect& aRect)
  1777. {
  1778.     if ((aRow < 1) || (numOfRows < 1) || (aRow + numOfRows - 1 > fNumOfRows))
  1779.     {
  1780. #if qDebugMsg && qRangeCheck
  1781.         fprintf(stderr, "fNumOfRows == %1d aRow == %1d", fNumOfRows, aRow);
  1782.         ProgramBreak("Range Check in RowToVRect");
  1783. #endif
  1784.  
  1785.         aRect = gZeroVRect;
  1786.     }
  1787.     else                                        // all the params look OK 
  1788.         {
  1789.         long height;
  1790.         long topEdge;
  1791.  
  1792.         if (fRowHeights->fNoOfChunks == 1)        // only one row height 
  1793.         {
  1794.             height = fRowHeights->GetValue(1);
  1795.             topEdge = height * (aRow - 1);
  1796.             height *= numOfRows;
  1797.         }
  1798.         else
  1799.         {
  1800.             topEdge = fRowHeights->SumValues(1, aRow - 1);
  1801.             height = fRowHeights->SumValues(aRow, numOfRows);
  1802.         }
  1803.  
  1804.         aRect = VRect(0, topEdge, fColWidths->fTotal, topEdge + height);
  1805.     }
  1806. } // TGridView::RowToVRect 
  1807.  
  1808. //----------------------------------------------------------------------------------------
  1809. // TGridView::ScrollSelectionIntoView: 
  1810. //----------------------------------------------------------------------------------------
  1811. #pragma segment GVRes
  1812.  
  1813. void TGridView::ScrollSelectionIntoView(Boolean redraw)
  1814. {
  1815.  
  1816.     if (this->IsAnyCellSelected())
  1817.     {
  1818.         VRect topLeftRect;
  1819.         VRect botRightRect;
  1820.         VRect selectionRect;
  1821.         
  1822.         CRect rgnBBox = (**fSelections).rgnBBox;
  1823.  
  1824.         this->CellToVRect(rgnBBox[topLeft], topLeftRect);
  1825.         GridCell botRightCell(rgnBBox.right - 1, rgnBBox.bottom - 1);
  1826.         this->CellToVRect(botRightCell, botRightRect);
  1827.         selectionRect = topLeftRect | botRightRect;
  1828.         long hCoord = Max(topLeftRect.GetLength(hSel), botRightRect.GetLength(hSel));
  1829.         VPoint minToSee(hCoord, Max(topLeftRect.GetLength(vSel), botRightRect.GetLength(vSel)));
  1830.         this->RevealRect(selectionRect, minToSee, redraw);
  1831.     }
  1832.     else
  1833.         Inherited::ScrollSelectionIntoView(redraw);
  1834. } // TGridView::ScrollSelectionIntoView 
  1835.  
  1836. //----------------------------------------------------------------------------------------
  1837. // TGridView::SetColWidth: 
  1838. //----------------------------------------------------------------------------------------
  1839. #pragma segment GVNonRes
  1840.  
  1841. void TGridView::SetColWidth(short aCol,
  1842.                                    short numOfCols,
  1843.                                    short aWidth)
  1844. {
  1845. #if qDebugMsg
  1846.     if ((aCol < 1) || (numOfCols < 1) || (aCol + numOfCols - 1 > fNumOfCols))
  1847.     {
  1848.         fprintf(stderr, "fNumOfCols == %1d aCol == %1d", fNumOfCols, aCol);
  1849.         ProgramBreak("Range Check in SetColWidth");
  1850.     }
  1851.     else
  1852. #endif
  1853.  
  1854.     if ((fColWidths->fNoOfChunks > 1) || (this->GetColWidth(1) != aWidth))
  1855.     {
  1856.         VRect aRect;
  1857.         long colMax = Max(1, aCol);            // to remove outlined inline warning
  1858.  
  1859.         // invalidate the old screen area of the cols
  1860.         this->ColToVRect((short)colMax, (short)Max(1, fNumOfCols - aCol + 1), aRect);
  1861.         this->InvalidateVRect(aRect);
  1862.  
  1863.         // set the new col widths and adjust the view's frame
  1864.         fColWidths->DeleteItems(aCol, numOfCols);
  1865.         fColWidths->InsertItems(aCol, numOfCols, aWidth);
  1866.         this->AdjustFrame();
  1867.  
  1868.         // invalidate the new screen area of the cols
  1869.         this->ColToVRect((short)colMax, (short)Max(1, fNumOfCols - aCol + 1), aRect);
  1870.         this->InvalidateVRect(aRect);
  1871.     }
  1872. } // TGridView::SetColWidth 
  1873.  
  1874. //----------------------------------------------------------------------------------------
  1875. // TGridView::SetRowHeight: 
  1876. //----------------------------------------------------------------------------------------
  1877. #pragma segment GVNonRes
  1878.  
  1879. void TGridView::SetRowHeight(short aRow,
  1880.                                     short numOfRows,
  1881.                                     short aHeight)
  1882. {
  1883. #if qDebugMsg
  1884.     if ((aRow < 1) || (numOfRows < 1) || (aRow + numOfRows - 1 > fNumOfRows))
  1885.     {
  1886.         fprintf(stderr, "fNumOfRows == %1d aRow == %1d", fNumOfRows, aRow);
  1887.         ProgramBreak("Range Check in SetRowHeight.");
  1888.     }
  1889.     else
  1890. #endif
  1891.  
  1892.     if ((fRowHeights->fNoOfChunks != 1) || (this->GetRowHeight(1) != aHeight))
  1893.     {
  1894.         VRect aVRect;
  1895.         long rowMax = Max(1, aRow);        // To remove outlined inline warning
  1896.  
  1897.         // invalidate the old screen area of the rows
  1898.         this->RowToVRect((short)rowMax, (short)Max(1, fNumOfRows - aRow + 1), aVRect);
  1899.         this->InvalidateVRect(aVRect);
  1900.  
  1901.         // set the new row height and adjust the view's frame
  1902.         fRowHeights->DeleteItems(aRow, numOfRows);
  1903.         fRowHeights->InsertItems(aRow, numOfRows, aHeight);
  1904.         this->AdjustFrame();
  1905.  
  1906.         // invalidate the new screen area of the rows
  1907.         this->RowToVRect((short)rowMax, (short)Max(1, fNumOfRows - aRow + 1), aVRect);
  1908.         this->InvalidateVRect(aVRect);
  1909.     }
  1910. } // TGridView::SetRowHeight 
  1911.  
  1912. //----------------------------------------------------------------------------------------
  1913. // TGridView::SelectCell: 
  1914. //----------------------------------------------------------------------------------------
  1915. #pragma segment GVRes
  1916.  
  1917. void TGridView::SelectCell(GridCell theCell,
  1918.                                   Boolean extendSelection,
  1919.                                   Boolean highlight,
  1920.                                   Boolean select)
  1921. {
  1922.     this->SetSelectionRect(CRect(theCell, theCell), extendSelection, highlight, select);
  1923. } // TGridView::SelectCell 
  1924.  
  1925. //----------------------------------------------------------------------------------------
  1926. // TGridView::SetEmptySelection: 
  1927. //----------------------------------------------------------------------------------------
  1928. #pragma segment GVRes
  1929.  
  1930. void TGridView::SetEmptySelection(Boolean highlight)
  1931. {
  1932.     SetEmptyRgn(fTemporarySelections);
  1933.     this->SetSelection(fTemporarySelections, kDontExtend, highlight, kSelect);
  1934. } // TGridView::SetEmptySelection 
  1935.  
  1936. //----------------------------------------------------------------------------------------
  1937. // TGridView::SetSelection: 
  1938. //----------------------------------------------------------------------------------------
  1939. #pragma segment GVRes
  1940.  
  1941. void TGridView::SetSelection(RgnHandle cellsToSelect,
  1942.                                     Boolean extendSelection,
  1943.                                     Boolean highlight,
  1944.                                     Boolean select)
  1945. {
  1946. #if qDebug
  1947.     CRect bounds = (**cellsToSelect).rgnBBox;
  1948.  
  1949.     if (fSingleSelection && ((bounds.GetLength(hSel) > 1) || (bounds.GetLength(vSel) > 1)))
  1950.         ProgramBreak("Attempt to select multiple cells when fSingleSelection is TRUE");
  1951.     if (!EmptyRgn(cellsToSelect))
  1952.         if ((bounds.left < 1) || (bounds.top < 1) || (bounds.right > fNumOfCols + 1) || (bounds.bottom > fNumOfRows + 1))
  1953.             ProgramBreak("Attempted selection is outside the range of cells");
  1954. #endif
  1955.  
  1956.     if (highlight)
  1957.         CopyRgn(fSelections, pPreviousSelection);// save the old selection 
  1958.  
  1959.     CTemporaryRegion tempRgn;
  1960.  
  1961.     SetRectRgn(tempRgn, 1, 1, fNumOfCols + 1, fNumOfRows + 1);
  1962.     SectRgn(cellsToSelect, tempRgn, tempRgn);
  1963.  
  1964.     if (extendSelection && select)                // extend the selection region 
  1965.         UnionRgn(tempRgn, fSelections, fSelections);
  1966.     else if (select)                            // reset the selection region 
  1967.         CopyRgn(tempRgn, fSelections);
  1968.     else                                        // need to de-select the new region 
  1969.         DiffRgn(fSelections, tempRgn, fSelections);
  1970.  
  1971.     this->UserSelectionChanged(this);            // so doc updates its designator 
  1972.  
  1973.     CopyRgn(fSelections, fHLRegion);
  1974.  
  1975.     if (highlight)
  1976.     {
  1977.         HLState currentHL = this->GetCurrentHL();
  1978.  
  1979.         // Turn the deselected cells off 
  1980.         DiffRgn(pPreviousSelection, fSelections, pDifference);
  1981.         this->HighlightCells(pDifference, currentHL, hlOff);
  1982.  
  1983.         // Turn the newly selected cells on 
  1984.         DiffRgn(fSelections, pPreviousSelection, pDifference);
  1985.         this->HighlightCells(pDifference, hlOff, currentHL);
  1986.     }
  1987. } // TGridView::SetSelection 
  1988.  
  1989. //----------------------------------------------------------------------------------------
  1990. // TGridView::SetSelectionRect: 
  1991. //----------------------------------------------------------------------------------------
  1992. #pragma segment GVRes
  1993.  
  1994. void TGridView::SetSelectionRect(const CRect& selectionRect,
  1995.                                         Boolean extendSelection,
  1996.                                         Boolean highlight,
  1997.                                         Boolean select)
  1998.  
  1999. {
  2000.     if (selectionRect == gZeroRect)
  2001.         SetEmptyRgn(fTemporarySelections);
  2002.     else
  2003.         SetRectRgn(fTemporarySelections, selectionRect.left, selectionRect.top, selectionRect.right + 1, selectionRect.bottom + 1);
  2004.  
  2005.     this->SetSelection(fTemporarySelections, extendSelection, highlight, select);
  2006. } // TGridView::SetSelectionRect 
  2007.  
  2008. //----------------------------------------------------------------------------------------
  2009. // TGridView::SetSingleSelection: 
  2010. //----------------------------------------------------------------------------------------
  2011. #pragma segment GVNonRes
  2012.  
  2013. void TGridView::SetSingleSelection(Boolean theSetting)
  2014. {
  2015.     fSingleSelection = theSetting;
  2016. } // TGridView::SetSingleSelection 
  2017.  
  2018. //----------------------------------------------------------------------------------------
  2019. // TGridView::VPointToCell: 
  2020. //----------------------------------------------------------------------------------------
  2021. #pragma segment GVRes
  2022.  
  2023. GridCell TGridView::VPointToCell(const VPoint& aPoint)
  2024. {
  2025.     GridCell aCell(fColWidths->FindItem(aPoint.h), fRowHeights->FindItem(aPoint.v));
  2026.  
  2027.     if ((aCell.h == 0) || (aCell.v == 0))
  2028.         return gZeroPt;
  2029.     else
  2030.         return aCell;
  2031. } // TGridView::VPointToCell 
  2032.  
  2033. //----------------------------------------------------------------------------------------
  2034. // TGridView::VPointToLastCell: 
  2035. //----------------------------------------------------------------------------------------
  2036. #pragma segment GVRes
  2037.  
  2038. GridCell TGridView::VPointToLastCell(const VPoint& aPoint)
  2039. {
  2040.     GridCell aCell;
  2041.  
  2042.     aCell.h = fColWidths->FindItem(aPoint.h);
  2043.     if (aCell.h == 0)                            // If its invalid, return the last column 
  2044.         aCell.h = fNumOfCols;
  2045.  
  2046.     aCell.v = fRowHeights->FindItem(aPoint.v);
  2047.     if (aCell.v == 0)                            // If its invalid, return the last row 
  2048.         aCell.v = fNumOfRows;
  2049.  
  2050.     return aCell;
  2051. } // TGridView::VPointToLastCell 
  2052.  
  2053.  
  2054. //========================================================================================
  2055. // CLASS TTextGridView
  2056. //========================================================================================
  2057. #undef Inherited
  2058. #define Inherited TGridView
  2059.  
  2060. #pragma segment GVOpen
  2061. DefineClass(TTextGridView, Inherited);
  2062.  
  2063. //----------------------------------------------------------------------------------------
  2064. // TTextGridView constructor
  2065. //----------------------------------------------------------------------------------------
  2066. #pragma segment GVOpen
  2067.  
  2068. TTextGridView::TTextGridView()
  2069. {
  2070.     fTextStyle = gSystemStyle;
  2071.     fTextStyleRsrcID = kNoResource;
  2072.     fJustification = teFlushDefault;
  2073.     fPreferOutline = kDontPreferOutline;
  2074.     fLineHeight = 0;
  2075.     fLineAscent = 0;
  2076. } // TTextGridView::TTextGridView
  2077.  
  2078. //----------------------------------------------------------------------------------------
  2079. // TTextGridView::ITextGridView: 
  2080. //----------------------------------------------------------------------------------------
  2081. #pragma segment GVOpen
  2082.  
  2083. void TTextGridView::ITextGridView(TDocument* itsDocument,
  2084.                                          // Its document 
  2085.                                          TView* itsSuperView,
  2086.                                          // Its parent view 
  2087.                                          const VPoint& itsLocation,
  2088.                                          // Top, Left in parent's coords 
  2089.                                          const VPoint& itsSize,
  2090.                                          SizeDeterminer itsHSizeDet,
  2091.                                          SizeDeterminer itsVSizeDet,
  2092.                                          // Size determiners 
  2093.                                          short numOfRows,
  2094.                                          // Number of rows initially 
  2095.                                          short numOfCols,
  2096.                                          // Number of columns initially 
  2097.                                          short rowHeight,
  2098.                                          // Row height, or zero for font height 
  2099.                                          short colWidth,
  2100.                                          // Width of items in the columns 
  2101.                                          Boolean adornRows,
  2102.                                          // Adornment for Rows? 
  2103.                                          Boolean adornCols,
  2104.                                          // Adornment for Columns? 
  2105.                                          short rowInset,
  2106.                                          // horizontal space between cells 
  2107.                                          short colInset,
  2108.                                          // vertical space between cells 
  2109.                                          Boolean singleSelection,
  2110.                                          // single cell selection? 
  2111.                                          const TextStyle& itsTextStyle)// size, color, etc. font info 
  2112.  
  2113. {
  2114.     if (rowHeight == 0)
  2115.     {
  2116.         // Compute the rowHeight for call to IGridView based on the line height and the row inset.
  2117.         GrafPtr savedPort;
  2118.         GetPort(&savedPort);                    // save the port
  2119.         SetPort(gWorkPort);                        // set port to the work port
  2120.  
  2121.         SetPortTextStyle(itsTextStyle);            // set the port's text style
  2122.         PenNormal();
  2123.  
  2124.         FontInfo theFontInfo;
  2125.         rowHeight = MAGetFontInfo(theFontInfo) + rowInset;
  2126.  
  2127.         SetPort(savedPort);                        // restore port
  2128.     }
  2129.  
  2130.     this->IGridView(itsDocument, itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, numOfRows, numOfCols, rowHeight, colWidth, adornRows, adornCols, rowInset, colInset, singleSelection);
  2131.  
  2132.     fTextStyle = itsTextStyle;
  2133.  
  2134.     this->SetUpFont();
  2135.  
  2136.     if ((fNumOfCols == 1) && (fSizeDeterminer[hSel] != sizeFixed) && (this->GetColWidth(1) == 0) && fSuperView)
  2137.         this->SetColWidth(1, fNumOfCols, (short)fSuperView->fSize.h);//!!! Note cast
  2138. } // TTextGridView::ITextGridView 
  2139.  
  2140. //----------------------------------------------------------------------------------------
  2141. // TTextGridView::GetStandardSignature: 
  2142. //----------------------------------------------------------------------------------------
  2143. #pragma segment GVWriteResource
  2144.  
  2145. IDType TTextGridView::GetStandardSignature()// override 
  2146. {
  2147.     return kStdTextGridView;
  2148. } // TTextGridView::GetStandardSignature 
  2149.  
  2150. //----------------------------------------------------------------------------------------
  2151. // TTextGridView::ReadFields: 
  2152. //----------------------------------------------------------------------------------------
  2153. #pragma segment GVReadResource
  2154.  
  2155. void TTextGridView::ReadFields(TStream* aStream)// override 
  2156. {
  2157.     Inherited::ReadFields(aStream);
  2158.  
  2159.     FailInfo fi;
  2160.     Try(fi)
  2161.     {
  2162.         fTextStyleRsrcID = aStream->ReadInteger();
  2163.         if (fTextStyleRsrcID != kNoResource)
  2164.         {
  2165.             TextStyle itsTextStyle;
  2166.             MAGetTextStyle(fTextStyleRsrcID, itsTextStyle);
  2167.             fTextStyle = itsTextStyle;
  2168.         }
  2169.  
  2170.         fPreferOutline = aStream->ReadBoolean();
  2171.         fi.Success();
  2172.     }
  2173.     else
  2174.     {
  2175.         this->Free();
  2176.         fi.ReSignal();
  2177.     }
  2178.  
  2179.     this->SetUpFont();
  2180.  
  2181.     if (fNumOfRows > 0)
  2182.         if (this->GetRowHeight(1) == 0)            // set row height from font 
  2183.             this->SetRowHeight(1, fNumOfRows, fLineHeight + fRowInset);
  2184.  
  2185.     if ((fNumOfCols == 1) && (fSizeDeterminer[hSel] != sizeFixed) && (this->GetColWidth(1) == 0))
  2186.         this->SetColWidth(1, fNumOfCols, (short)fSize.h);//!!! Note cast
  2187. } // TTextGridView::ReadFields 
  2188.  
  2189. //----------------------------------------------------------------------------------------
  2190. // TTextGridView::WriteFields: 
  2191. //----------------------------------------------------------------------------------------
  2192. #pragma segment GVWriteResource
  2193.  
  2194. void TTextGridView::WriteFields(TStream* aStream)// override 
  2195. {
  2196.     Inherited::WriteFields(aStream);
  2197.  
  2198.     aStream->WriteInteger(fTextStyleRsrcID);
  2199.     aStream->WriteBoolean(fPreferOutline);
  2200. } // TTextGridView::WriteFields 
  2201.  
  2202. //----------------------------------------------------------------------------------------
  2203. // TTextGridView::DrawCell: 
  2204. //----------------------------------------------------------------------------------------
  2205. #pragma segment GVRes
  2206.  
  2207. void TTextGridView::DrawCell(GridCell aCell,
  2208.                                     const VRect& aRect)// override 
  2209. {
  2210.     CStr255 theText;
  2211.  
  2212.     this->GetText(aCell, theText);
  2213.  
  2214.     if (this->GetColWidth(aCell.h) > 0)
  2215.     {
  2216.         CRect r;
  2217.  
  2218.         this->ViewToQDRect(aRect, r);
  2219.         MADrawString(theText, r, fJustification, fPreferOutline);
  2220.     }
  2221. } // TTextGridView::DrawCell 
  2222.  
  2223. //----------------------------------------------------------------------------------------
  2224. // TTextGridView::Focus: 
  2225. //----------------------------------------------------------------------------------------
  2226. #pragma segment GVRes
  2227.  
  2228. Boolean TTextGridView::Focus()            // override 
  2229. {
  2230.     if (Inherited::Focus())
  2231.     {
  2232.         this->SetPen();
  2233.         return TRUE;
  2234.     }
  2235.     else
  2236.         return FALSE;
  2237. } // TTextGridView::Focus 
  2238.  
  2239. //----------------------------------------------------------------------------------------
  2240. // TTextGridView::SetUpFont: 
  2241. //----------------------------------------------------------------------------------------
  2242. #pragma segment GVOpen
  2243.  
  2244. void TTextGridView::SetUpFont()
  2245. {
  2246.     GrafPtr savedPort;
  2247.  
  2248.     // set port to the work port
  2249.     GetPort(&savedPort);
  2250.     SetPort(gWorkPort);
  2251.  
  2252.     {                                            // block for CWhileOutlinePreferred (which has a constructor/destructor)
  2253.         CWhileOutlinePreferred setOP(fPreferOutline);
  2254.         FontInfo theFontInfo;
  2255.  
  2256.         this->SetPen();
  2257.         fLineHeight = MAGetFontInfo(theFontInfo);// returns height of font 
  2258.         fLineAscent = theFontInfo.ascent + (theFontInfo.leading / 2);
  2259.     }
  2260.  
  2261.     // restore port
  2262.     SetPort(savedPort);
  2263. } // TTextGridView::SetUpFont 
  2264.  
  2265. //----------------------------------------------------------------------------------------
  2266. // TTextGridView::SetPen: 
  2267. //----------------------------------------------------------------------------------------
  2268. #pragma segment GVRes
  2269.  
  2270. void TTextGridView::SetPen()
  2271. {
  2272.     TextStyle itsTextStyle = fTextStyle;
  2273.     SetPortTextStyle(itsTextStyle);
  2274.     PenNormal();
  2275. } // TTextGridView::SetPen 
  2276.  
  2277. //----------------------------------------------------------------------------------------
  2278. // TTextGridView::GetText: 
  2279. //----------------------------------------------------------------------------------------
  2280. #pragma segment GVRes
  2281.  
  2282. void TTextGridView::GetText(GridCell        /* aCell */,
  2283.                                    CStr255&    aString )
  2284. {
  2285.     aString = gEmptyString;
  2286. } // TTextGridView::GetText 
  2287.  
  2288.  
  2289. //========================================================================================
  2290. // CLASS TTextListView
  2291. //========================================================================================
  2292. #undef Inherited
  2293. #define Inherited TTextGridView
  2294.  
  2295. #pragma segment GVOpen
  2296. DefineClass(TTextListView, Inherited);
  2297.  
  2298. //----------------------------------------------------------------------------------------
  2299. // TTextListView::TTextListView: Empty constructor to satisfy the compiler.
  2300. //----------------------------------------------------------------------------------------
  2301. #pragma segment GVOpen
  2302.  
  2303. TTextListView::TTextListView()
  2304. {
  2305. } // TTextListView::TTextListView
  2306.  
  2307. //----------------------------------------------------------------------------------------
  2308. // TTextListView::ITextListView: 
  2309. //----------------------------------------------------------------------------------------
  2310. #pragma segment GVOpen
  2311.  
  2312. void TTextListView::ITextListView(TDocument* itsDocument,
  2313.                                          // Its document 
  2314.                                          TView* itsSuperView,
  2315.                                          // Its parent view 
  2316.                                          const VPoint& itsLocation,
  2317.                                          // Top, Left in parent's coords 
  2318.                                          const VPoint& itsSize,
  2319.                                          SizeDeterminer itsHSizeDet,
  2320.                                          SizeDeterminer itsVSizeDet,
  2321.                                          // Size determiners 
  2322.                                          short numOfItems,
  2323.                                          // Number of items initially 
  2324.                                          short rowHeight,
  2325.                                          // Row height, or zero for font height 
  2326.                                          short colWidth,
  2327.                                          // Width of items in the columns 
  2328.                                          Boolean adornRows,
  2329.                                          // Draw the row adornments? 
  2330.                                          Boolean adornCols,
  2331.                                          // Draw the col adornment? 
  2332.                                          short rowInset,
  2333.                                          // Amount to inset the rows 
  2334.                                          short colInset,
  2335.                                          // Amount to inset the column 
  2336.                                          Boolean singleSelection,
  2337.                                          // single cell selection? 
  2338.                                          const TextStyle& itsTextStyle)// size, color, etc. font info 
  2339.  
  2340. {
  2341.     this->ITextGridView(itsDocument, itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, numOfItems, 1, rowHeight, colWidth, adornRows, adornCols, rowInset, colInset, singleSelection, itsTextStyle);
  2342. } // TTextListView::ITextListView 
  2343.  
  2344. //----------------------------------------------------------------------------------------
  2345. // TTextListView::GetStandardSignature: 
  2346. //----------------------------------------------------------------------------------------
  2347. #pragma segment GVWriteResource
  2348.  
  2349. IDType TTextListView::GetStandardSignature()// override 
  2350. {
  2351.     return kStdTextListView;
  2352. } // TTextListView::GetStandardSignature 
  2353.  
  2354. //----------------------------------------------------------------------------------------
  2355. // TTextListView::CanSelectCell: 
  2356. //----------------------------------------------------------------------------------------
  2357. #pragma segment GVRes
  2358.  
  2359. Boolean TTextListView::CanSelectCell(GridCell aCell)// override 
  2360. {
  2361.     return (Inherited::CanSelectCell(aCell) && this->CanSelectItem(aCell.v));
  2362. } // TTextListView::CanSelectCell 
  2363.  
  2364. //----------------------------------------------------------------------------------------
  2365. // TTextListView::CanSelectItem: 
  2366. //----------------------------------------------------------------------------------------
  2367. #pragma segment GVRes
  2368.  
  2369. Boolean TTextListView::CanSelectItem(short anItem)
  2370. {
  2371.     return ((anItem >= 1) && (anItem <= fNumOfRows));
  2372. } // TTextListView::CanSelectItem 
  2373.  
  2374. //----------------------------------------------------------------------------------------
  2375. // TTextListView::DelItemAt: 
  2376. //----------------------------------------------------------------------------------------
  2377. #pragma segment GVNonRes
  2378.  
  2379. void TTextListView::DelItemAt(short anItem,
  2380.                                      short numOfItems)
  2381. {
  2382.     this->DelRowAt(anItem, numOfItems);
  2383. } // TTextListView::DelItemAt 
  2384.  
  2385. //----------------------------------------------------------------------------------------
  2386. // TTextListView::DelItemFirst: 
  2387. //----------------------------------------------------------------------------------------
  2388. #pragma segment GVNonRes
  2389.  
  2390. void TTextListView::DelItemFirst(short numOfItems)
  2391. {
  2392.     this->DelItemAt(1, numOfItems);
  2393. } // TTextListView::DelItemFirst 
  2394.  
  2395. //----------------------------------------------------------------------------------------
  2396. // TTextListView::DelItemLast: 
  2397. //----------------------------------------------------------------------------------------
  2398. #pragma segment GVNonRes
  2399.  
  2400. void TTextListView::DelItemLast(short numOfItems)
  2401. {
  2402.     this->DelItemAt(fNumOfRows - numOfItems + 1, numOfItems);
  2403. } // TTextListView::DelItemLast 
  2404.  
  2405. //----------------------------------------------------------------------------------------
  2406. // TTextListView::DoKeySelection: 
  2407. //----------------------------------------------------------------------------------------
  2408. #pragma segment GVRes
  2409.  
  2410. void TTextListView::DoKeySelection(const CStr255& selectionString)
  2411. {
  2412.     CStr255 itemText;
  2413.     short itemIndex;
  2414.     short lastItemIndex = GetItemIndexOrdered(1);
  2415.  
  2416.     for (short i = 1; i <= fNumOfRows; i++)
  2417.     {
  2418.         itemIndex = GetItemIndexOrdered(i);
  2419.         GetItemText(itemIndex, itemText);
  2420.         itemText.Delete(selectionString.Length() + 1, itemText.Length() - selectionString.Length());
  2421.         lastItemIndex = itemIndex;
  2422.         if (itemText >= selectionString)
  2423.             break;
  2424.     }
  2425.  
  2426.     this->SelectItem(lastItemIndex, FALSE, TRUE, TRUE);
  2427.     this->ScrollSelectionIntoView(TRUE);
  2428. } // TTextListView::DoKeySelection 
  2429.  
  2430. //----------------------------------------------------------------------------------------
  2431. // TTextListView::FirstSelectedItem: 
  2432. //----------------------------------------------------------------------------------------
  2433. #pragma segment GVRes
  2434.  
  2435. short TTextListView::FirstSelectedItem()
  2436. {
  2437.     GridCell aGridCell(this->FirstSelectedCell());
  2438.     return aGridCell.v;
  2439. } // TTextListView::FirstSelectedItem 
  2440.  
  2441. //----------------------------------------------------------------------------------------
  2442. // TTextListView::GetItemHeight: 
  2443. //----------------------------------------------------------------------------------------
  2444. #pragma segment GVRes
  2445.  
  2446. short TTextListView::GetItemHeight(short anItem)
  2447. {
  2448.     return this->GetRowHeight(anItem);
  2449. } // TTextListView::GetItemHeight 
  2450.  
  2451. //----------------------------------------------------------------------------------------
  2452. // TTextListView::GetItemWidth: 
  2453. //----------------------------------------------------------------------------------------
  2454. #pragma segment GVRes
  2455.  
  2456. short TTextListView::GetItemWidth()
  2457. {
  2458.     return this->GetColWidth(1);
  2459. } // TTextListView::GetItemWidth 
  2460.  
  2461. //----------------------------------------------------------------------------------------
  2462. // TTextListView::GetItemText: 
  2463. //----------------------------------------------------------------------------------------
  2464. #pragma segment GVRes
  2465.  
  2466. void TTextListView::GetItemText(short,
  2467.                                        CStr255& aString)
  2468. {
  2469.     aString = gEmptyString;
  2470. } // TTextListView::GetItemText 
  2471.  
  2472. //----------------------------------------------------------------------------------------
  2473. // TTextListView::GetItemIndexOrdered: 
  2474. //----------------------------------------------------------------------------------------
  2475. #pragma segment GVRes
  2476.  
  2477. short TTextListView::GetItemIndexOrdered(short nthItem)
  2478. {
  2479.     return nthItem;
  2480. } // TTextListView::GetItemIndexOrdered 
  2481.  
  2482. //----------------------------------------------------------------------------------------
  2483. // TTextListView::GetText: 
  2484. //----------------------------------------------------------------------------------------
  2485. #pragma segment GVRes
  2486.  
  2487. void TTextListView::GetText(GridCell aCell,
  2488.                                    CStr255& aString)// override 
  2489. {
  2490.     this->GetItemText(aCell.v, aString);
  2491. } // TTextListView::GetText 
  2492.  
  2493. //----------------------------------------------------------------------------------------
  2494. // TTextListView::InsItemBefore: 
  2495. //----------------------------------------------------------------------------------------
  2496. #pragma segment GVRes
  2497.  
  2498. void TTextListView::InsItemBefore(short anItem,
  2499.                                          short numOfItems)
  2500. {
  2501.     this->InsRowBefore(anItem, numOfItems, fLineHeight + fRowInset);
  2502. } // TTextListView::InsItemBefore 
  2503.  
  2504. //----------------------------------------------------------------------------------------
  2505. // TTextListView::InsItemFirst: 
  2506. //----------------------------------------------------------------------------------------
  2507. #pragma segment GVRes
  2508.  
  2509. void TTextListView::InsItemFirst(short numOfItems)
  2510. {
  2511.     this->InsItemBefore(1, numOfItems);
  2512. } // TTextListView::InsItemFirst 
  2513.  
  2514. //----------------------------------------------------------------------------------------
  2515. // TTextListView::InsItemLast: 
  2516. //----------------------------------------------------------------------------------------
  2517. #pragma segment GVRes
  2518.  
  2519. void TTextListView::InsItemLast(short numOfItems)
  2520. {
  2521.     this->InsItemBefore(fNumOfRows + 1, numOfItems);
  2522. } // TTextListView::InsItemLast 
  2523.  
  2524. //----------------------------------------------------------------------------------------
  2525. // TTextListView::InvalidateItem: 
  2526. //----------------------------------------------------------------------------------------
  2527. #pragma segment GVRes
  2528.  
  2529. void TTextListView::InvalidateItem(short anItem)
  2530. {
  2531.     GridCell aCell(1, anItem);
  2532.     this->InvalidateCell(aCell);
  2533. } // TTextListView::InvalidateItem 
  2534.  
  2535. //----------------------------------------------------------------------------------------
  2536. // TTextListView::IsItemSelected: 
  2537. //----------------------------------------------------------------------------------------
  2538. #pragma segment GVRes
  2539.  
  2540. Boolean TTextListView::IsItemSelected(short anItem)
  2541. {
  2542.     GridCell aCell(1, anItem);
  2543.     return this->IsCellSelected(aCell);
  2544. } // TTextListView::IsItemSelected 
  2545.  
  2546. //----------------------------------------------------------------------------------------
  2547. // TTextListView::LastSelectedItem: 
  2548. //----------------------------------------------------------------------------------------
  2549. #pragma segment GVRes
  2550.  
  2551. short TTextListView::LastSelectedItem()
  2552. {
  2553.     GridCell aGridCell(this->LastSelectedCell());
  2554.     return aGridCell.v;
  2555. } // TTextListView::LastSelectedItem 
  2556.  
  2557. //----------------------------------------------------------------------------------------
  2558. // TTextListView::SetFrame: 
  2559. //----------------------------------------------------------------------------------------
  2560. #pragma segment GVNonRes
  2561.  
  2562. void TTextListView::SetFrame(const VRect& newFrame,
  2563.                                     Boolean invalidate)// override 
  2564. {
  2565.     VPoint oldSize(fSize);
  2566.  
  2567.     Inherited::SetFrame(newFrame, invalidate);
  2568.  
  2569.     if (fNumOfCols == 1 && fSize != oldSize)
  2570.     {
  2571.         fColWidths->fTotal += fSize.h - (*(fColWidths->fChunks))[0].value;
  2572.         (*(fColWidths->fChunks))[0].value = (short)fSize.h;//!!! Note cast
  2573.     }
  2574. } // TTextListView::SetFrame 
  2575.  
  2576. //----------------------------------------------------------------------------------------
  2577. // TTextListView::SelectCell: 
  2578. //----------------------------------------------------------------------------------------
  2579. #pragma segment GVRes
  2580.  
  2581. void TTextListView::SelectCell(GridCell theCell,
  2582.                                       Boolean extendSelection,
  2583.                                       Boolean highlight,
  2584.                                       Boolean select)// override 
  2585. {
  2586.     this->SelectItem(theCell.v, extendSelection, highlight, select);
  2587. } // TTextListView::SelectCell 
  2588.  
  2589. //----------------------------------------------------------------------------------------
  2590. // TTextListView::SelectItem: 
  2591. //----------------------------------------------------------------------------------------
  2592. #pragma segment GVRes
  2593.  
  2594. void TTextListView::SelectItem(short anItem,
  2595.                                       Boolean extendSelection,
  2596.                                       Boolean highlight,
  2597.                                       Boolean select)
  2598. {
  2599.     GridCell aCell((short)Min(1, anItem), anItem);
  2600.  
  2601.     Inherited::SelectCell(aCell, extendSelection, highlight, select);
  2602. } // TTextListView::SelectItem 
  2603.  
  2604. //----------------------------------------------------------------------------------------
  2605. // TTextListView::SetItemHeight: 
  2606. //----------------------------------------------------------------------------------------
  2607. #pragma segment GVNonRes
  2608.  
  2609. void TTextListView::SetItemHeight(short anItem,
  2610.                                          short numOfItems,
  2611.                                          short aHeight)
  2612. {
  2613.     this->SetRowHeight(anItem, numOfItems, aHeight);
  2614. } // TTextListView::SetItemHeight 
  2615.  
  2616. //----------------------------------------------------------------------------------------
  2617. // TTextListView::SetItemWidth: 
  2618. //----------------------------------------------------------------------------------------
  2619. #pragma segment GVNonRes
  2620.  
  2621. void TTextListView::SetItemWidth(short aWidth)
  2622. {
  2623.     this->SetColWidth(1, 1, aWidth);
  2624. } // TTextListView::SetItemWidth 
  2625.  
  2626.  
  2627. //========================================================================================
  2628. // CLASS TCellSelectCommand
  2629. //========================================================================================
  2630. #undef Inherited
  2631. #define Inherited TTracker
  2632.  
  2633. #pragma segment GVSelCommand
  2634. DefineClass(TCellSelectCommand, Inherited);
  2635.  
  2636. //----------------------------------------------------------------------------------------
  2637. // TCellSelectCommand constructor
  2638. //----------------------------------------------------------------------------------------
  2639. #pragma segment GVSelCommand
  2640.  
  2641. TCellSelectCommand::TCellSelectCommand()
  2642. {
  2643.     fAnchorCell = gZeroPt;                        // At least set it to something 
  2644.     fCommandKey = FALSE;
  2645.     fDeselecting = FALSE;
  2646.     fDifference = NULL;
  2647.     fGridView = NULL;
  2648.     fPreviousCell = CPoint(-1, -1);
  2649.     fPreviousSelection = NULL;
  2650.     fShiftKey = FALSE;
  2651.     fThisSelection = NULL;
  2652. } // TCellSelectCommand::TCellSelectCommand
  2653.  
  2654. //----------------------------------------------------------------------------------------
  2655. // TCellSelectCommand::ICellSelectCommand: 
  2656. //----------------------------------------------------------------------------------------
  2657. #pragma segment GVSelCommand
  2658.  
  2659. void TCellSelectCommand::ICellSelectCommand(TGridView* itsView,
  2660.                                                    const VPoint& itsMouse,
  2661.                                                    Boolean theShiftKey,
  2662.                                                    Boolean theCommandKey)
  2663. {
  2664.     this->ITracker(cNoCommand, itsView, kCantUndo, kDoesNotCauseChange, NULL, itsView,
  2665.                     itsView->GetScroller(kAnySuperView), itsMouse);
  2666.     fShiftKey = theShiftKey;
  2667.     fCommandKey = theCommandKey;
  2668.     fViewConstrain = FALSE;
  2669.  
  2670.     fGridView = itsView;
  2671.  
  2672.     FailInfo fi;
  2673.     Try(fi)
  2674.     {
  2675.         fPreviousSelection = MakeNewRgn();
  2676.         CopyRgn(fGridView->fSelections, fPreviousSelection);
  2677.         fThisSelection = fGridView->fHLRegion;
  2678.         SetEmptyRgn(fThisSelection);
  2679.         fDifference = MakeNewRgn();
  2680.         fi.Success();
  2681.     }
  2682.     else                                        // Recover
  2683.     {
  2684.         this->Free();
  2685.         fi.ReSignal();
  2686.     }
  2687. } // TCellSelectCommand::ICellSelectCommand 
  2688.  
  2689. //----------------------------------------------------------------------------------------
  2690. // TCellSelectCommand::Free: 
  2691. //----------------------------------------------------------------------------------------
  2692. #pragma segment GVDoCommand
  2693.  
  2694. void TCellSelectCommand::Free()            // override 
  2695. {
  2696.     fPreviousSelection = DisposeIfRgnHandle(fPreviousSelection);
  2697.     fDifference = DisposeIfRgnHandle(fDifference);
  2698.  
  2699.     fThisSelection = NULL;                        // I don't own it so I don't dispose it.
  2700.                                                 // But, I sure don't need a reference to
  2701.                                                 // it any more.
  2702.  
  2703.     Inherited::Free();
  2704. } // TCellSelectCommand::Free 
  2705.  
  2706. //----------------------------------------------------------------------------------------
  2707. // TCellSelectCommand::ComputeAnchorCell: 
  2708. //----------------------------------------------------------------------------------------
  2709. #pragma segment GVDoCommand
  2710.  
  2711. void TCellSelectCommand::ComputeAnchorCell(GridCell& clickedCell)
  2712. {
  2713.     fAnchorCell = clickedCell;
  2714.  
  2715.     if (fShiftKey && (!EmptyRgn(fPreviousSelection)))
  2716.     {
  2717.         const CRect & bounds = (**fPreviousSelection).rgnBBox;
  2718.  
  2719.         if (fAnchorCell.h >= bounds.left)
  2720.             fAnchorCell.h = bounds.left;
  2721.         else
  2722.             fAnchorCell.h = bounds.right - 1;
  2723.         if (fAnchorCell.v >= bounds.top)
  2724.             fAnchorCell.v = bounds.top;
  2725.         else
  2726.             fAnchorCell.v = bounds.bottom - 1;
  2727.     }
  2728. } // TCellSelectCommand::ComputeAnchorCell 
  2729.  
  2730. //----------------------------------------------------------------------------------------
  2731. // TCellSelectCommand::ComputeNewSelection: 
  2732. //----------------------------------------------------------------------------------------
  2733. #pragma segment GVDoCommand
  2734.  
  2735. void TCellSelectCommand::ComputeNewSelection(GridCell& clickedCell)
  2736. {
  2737.     if (fGridView->CanSelectCell(clickedCell))
  2738.     {
  2739.         CRect r;
  2740.  
  2741.         if (fGridView->fSingleSelection || (!fShiftKey))
  2742.             SetRect(r, clickedCell.h, clickedCell.v, clickedCell.h + 1, clickedCell.v + 1);
  2743.         else
  2744.         {
  2745.             Pt2Rect(fAnchorCell, clickedCell, r);
  2746.             ++r.right;
  2747.             ++r.bottom;
  2748.         }
  2749.         RectRgn(fThisSelection, r);
  2750.         if (fCommandKey && (!fGridView->fSingleSelection))
  2751.             if (fDeselecting)
  2752.                 DiffRgn(fPreviousSelection, fThisSelection, fThisSelection);
  2753.             else
  2754.                 UnionRgn(fPreviousSelection, fThisSelection, fThisSelection);
  2755.     }
  2756. } // TCellSelectCommand::ComputeNewSelection 
  2757.  
  2758. //----------------------------------------------------------------------------------------
  2759. // TCellSelectCommand::HighlightNewSelection: 
  2760. //----------------------------------------------------------------------------------------
  2761. #pragma segment GVDoCommand
  2762.  
  2763. void TCellSelectCommand::HighlightNewSelection()
  2764. {
  2765.     // Turn off previously selected cells 
  2766.     DiffRgn(fPreviousSelection, fThisSelection, fDifference);
  2767.     fGridView->HighlightCells(fDifference, hlOn, hlOff);
  2768.  
  2769.     // Turn on newly selected cells
  2770.     DiffRgn(fThisSelection, fPreviousSelection, fDifference);
  2771.     fGridView->HighlightCells(fDifference, hlOff, hlOn);
  2772. } // TCellSelectCommand::HighlightNewSelection 
  2773.  
  2774. //----------------------------------------------------------------------------------------
  2775. // TCellSelectCommand::TrackFeedback: 
  2776. //----------------------------------------------------------------------------------------
  2777. #pragma segment GVDoCommand
  2778.  
  2779. void TCellSelectCommand::TrackFeedback(TrackPhase/* aTrackPhase */,
  2780.                                               const VPoint&/* anchorPoint */ ,
  2781.                                               const VPoint&/* previousPoint */ ,
  2782.                                               const VPoint&/* nextPoint */ ,
  2783.                                               Boolean/* mouseDidMove */,
  2784.                                               Boolean/* turnItOn */)// override 
  2785. {
  2786. } // TCellSelectCommand::TrackFeedback 
  2787.  
  2788. //----------------------------------------------------------------------------------------
  2789. // TCellSelectCommand::TrackMouse: 
  2790. //----------------------------------------------------------------------------------------
  2791. #pragma segment GVDoCommand
  2792.  
  2793. TTracker* TCellSelectCommand::TrackMouse(TrackPhase aTrackPhase,
  2794.                                                 VPoint&/* anchorPoint */ ,
  2795.                                                 VPoint&/* previousPoint */ ,
  2796.                                                 VPoint& nextPoint,
  2797.                                                 Boolean mouseDidMove)// override 
  2798. {
  2799.     if (mouseDidMove)
  2800.     {
  2801.         GridCell clickedCell;
  2802.         VPoint clippedPoint = nextPoint;
  2803.         VRect viewExtent;
  2804.  
  2805.         fGridView->GetExtent(viewExtent);
  2806.         clippedPoint.ConstrainTo(viewExtent);
  2807.         clickedCell = fGridView->VPointToCell(clippedPoint);
  2808.         if (aTrackPhase == trackBegin)
  2809.         {
  2810.             this->ComputeAnchorCell(clickedCell);
  2811.             if (fCommandKey)
  2812.                 fDeselecting = PtInRgn(fAnchorCell, fGridView->fSelections);
  2813.         }
  2814.  
  2815.         if (clickedCell != fPreviousCell)
  2816.         {
  2817.             this->ComputeNewSelection(clickedCell);
  2818.             this->HighlightNewSelection();
  2819.  
  2820.             CopyRgn(fThisSelection, fPreviousSelection);
  2821.             fPreviousCell = clickedCell;
  2822.         }
  2823.     }
  2824.     return this;
  2825. } // TCellSelectCommand::TrackMouse 
  2826.  
  2827. //----------------------------------------------------------------------------------------
  2828. // TCellSelectCommand::DoIt: 
  2829. //----------------------------------------------------------------------------------------
  2830. #pragma segment GVDoCommand
  2831.  
  2832. void TCellSelectCommand::DoIt()            // override 
  2833. {
  2834.     if (fGridView->fSingleSelection)
  2835.         fGridView->SelectCell(((CRect &) (*fThisSelection)->rgnBBox)[topLeft], kDontExtend, kDontHighlight, kSelect);
  2836.     else
  2837.         fGridView->SetSelection(fThisSelection, kDontExtend, kDontHighlight, kSelect);
  2838. } // TCellSelectCommand::DoIt 
  2839.  
  2840.  
  2841. //========================================================================================
  2842. // CLASS TRCSelectCommand
  2843. //========================================================================================
  2844. #undef Inherited
  2845. #define Inherited TCellSelectCommand
  2846.  
  2847. #pragma segment GVSelCommand
  2848. DefineClass(TRCSelectCommand, Inherited);
  2849.  
  2850. //----------------------------------------------------------------------------------------
  2851. // TRCSelectCommand::TRCSelectCommand: Empty constructor to satisfy the compiler.
  2852. //----------------------------------------------------------------------------------------
  2853. #pragma segment ConstructorRes
  2854.  
  2855. TRCSelectCommand::TRCSelectCommand()
  2856. {
  2857. } // TRCSelectCommand::TRCSelectCommand
  2858.  
  2859. //----------------------------------------------------------------------------------------
  2860. // TRCSelectCommand::IRCSelectCommand: 
  2861. //----------------------------------------------------------------------------------------
  2862. #pragma segment GVSelCommand
  2863.  
  2864. void TRCSelectCommand::IRCSelectCommand(TGridView* itsView,
  2865.                                                    const VPoint& itsMouse,
  2866.                                                    Boolean theShiftKey,
  2867.                                                    Boolean theCommandKey)
  2868. {
  2869.     this->ICellSelectCommand(itsView, itsMouse, theShiftKey, theCommandKey);
  2870. } // TRCSelectCommand::IRCSelectCommand
  2871.  
  2872. //----------------------------------------------------------------------------------------
  2873. // TRCSelectCommand::ComputeNewSelection: 
  2874. //----------------------------------------------------------------------------------------
  2875. #pragma segment GVDoCommand
  2876.  
  2877. void TRCSelectCommand::ComputeNewSelection(GridCell& clickedCell)// override 
  2878. {
  2879.     if (fGridView->CanSelectCell(clickedCell))
  2880.     {
  2881.         CRect r;
  2882.  
  2883.         if (fGridView->fSingleSelection)
  2884.             r = CRect(clickedCell.h, clickedCell.v, clickedCell.h + 1, clickedCell.v + 1);
  2885.         else
  2886.         {
  2887.             Pt2Rect(fAnchorCell, clickedCell, r);
  2888.             ++r.right;
  2889.             ++r.bottom;
  2890.         }
  2891.         RectRgn(fThisSelection, r);
  2892.         if (fCommandKey && (!fGridView->fSingleSelection))
  2893.             if (fDeselecting)
  2894.                 DiffRgn(fPreviousSelection, fThisSelection, fThisSelection);
  2895.             else
  2896.                 UnionRgn(fPreviousSelection, fThisSelection, fThisSelection);
  2897.     }
  2898. } // TRCSelectCommand::ComputeNewSelection 
  2899.  
  2900. //----------------------------------------------------------------------------------------
  2901. // TRCSelectCommand::TrackMouse: 
  2902. //----------------------------------------------------------------------------------------
  2903. #pragma segment GVDoCommand
  2904.  
  2905. TTracker* TRCSelectCommand::TrackMouse(TrackPhase aTrackPhase,
  2906.                                               VPoint&/* anchorPoint */ ,
  2907.                                               VPoint&/* previousPoint */ ,
  2908.                                               VPoint& nextPoint,
  2909.                                               Boolean mouseDidMove)// override 
  2910. {
  2911.     GridCell clickedCell;
  2912.     VRect viewExtent;
  2913.     VPoint clippedPoint;
  2914.  
  2915.     if (mouseDidMove)
  2916.     {
  2917.         fGridView->GetExtent(viewExtent);
  2918.         clippedPoint = nextPoint;
  2919.         clippedPoint.ConstrainTo(viewExtent);
  2920.         clickedCell = fGridView->VPointToCell(clippedPoint);
  2921.         if (aTrackPhase == trackBegin)
  2922.         {
  2923.             this->ComputeAnchorCell(clickedCell);
  2924.             if (fCommandKey)
  2925.                 fDeselecting = PtInRgn(fAnchorCell, fGridView->fSelections);
  2926.         }
  2927.  
  2928.         if (clickedCell != fPreviousCell)
  2929.         {
  2930.             if (!fShiftKey && (aTrackPhase != trackBegin))
  2931.             {
  2932.                 this->ComputeAnchorCell(clickedCell);
  2933.                 if (fCommandKey)
  2934.                     fDeselecting = PtInRgn(fAnchorCell, fGridView->fSelections);
  2935.             }
  2936.             this->ComputeNewSelection(clickedCell);
  2937.             this->HighlightNewSelection();
  2938.  
  2939.             CopyRgn(fThisSelection, fPreviousSelection);
  2940.             fPreviousCell = clickedCell;
  2941.         }
  2942.     }
  2943.     return this;
  2944. } // TRCSelectCommand::TrackMouse 
  2945.  
  2946.  
  2947. //========================================================================================
  2948. // CLASS TRowSelectCommand
  2949. //========================================================================================
  2950. #undef Inherited
  2951. #define Inherited TRCSelectCommand
  2952.  
  2953. #pragma segment GVSelCommand
  2954. DefineClass(TRowSelectCommand, Inherited);
  2955.  
  2956. //----------------------------------------------------------------------------------------
  2957. // TRowSelectCommand::TRowSelectCommand: Empty constructor to satisfy the compiler.
  2958. //----------------------------------------------------------------------------------------
  2959. #pragma segment ConstructorRes
  2960.  
  2961. TRowSelectCommand::TRowSelectCommand()
  2962. {
  2963. } // TRowSelectCommand::TRowSelectCommand
  2964.  
  2965. //----------------------------------------------------------------------------------------
  2966. // TRowSelectCommand::IRowSelectCommand: 
  2967. //----------------------------------------------------------------------------------------
  2968. #pragma segment GVSelCommand
  2969.  
  2970. void TRowSelectCommand::IRowSelectCommand(TGridView* itsView,
  2971.                                                  const VPoint& itsMouse,
  2972.                                                  Boolean theShiftKey,
  2973.                                                  Boolean theCommandKey)
  2974. {
  2975.     this->IRCSelectCommand(itsView, itsMouse, theShiftKey, theCommandKey);
  2976. } // TRowSelectCommand::IRowSelectCommand 
  2977.  
  2978. //----------------------------------------------------------------------------------------
  2979. // TRowSelectCommand::ComputeAnchorCell: 
  2980. //----------------------------------------------------------------------------------------
  2981. #pragma segment GVDoCommand
  2982.  
  2983. void TRowSelectCommand::ComputeAnchorCell(GridCell& clickedCell)// override 
  2984. {
  2985.     Inherited::ComputeAnchorCell(clickedCell);
  2986.     fAnchorCell.h = 1;
  2987. } // TRowSelectCommand::ComputeAnchorCell 
  2988.  
  2989. //----------------------------------------------------------------------------------------
  2990. // TRowSelectCommand::ComputeNewSelection: 
  2991. //----------------------------------------------------------------------------------------
  2992. #pragma segment GVDoCommand
  2993.  
  2994. void TRowSelectCommand::ComputeNewSelection(GridCell& clickedCell)// override 
  2995. {
  2996.     clickedCell.h = fGridView->fNumOfCols;
  2997.  
  2998.     Inherited::ComputeNewSelection(clickedCell);
  2999. } // TRowSelectCommand::ComputeNewSelection 
  3000.  
  3001.  
  3002. //========================================================================================
  3003. // CLASS TColumnSelectCommand
  3004. //========================================================================================
  3005. #undef Inherited
  3006. #define Inherited TRCSelectCommand
  3007.  
  3008. #pragma segment GVSelCommand
  3009. DefineClass(TColumnSelectCommand, Inherited);
  3010.  
  3011. //----------------------------------------------------------------------------------------
  3012. // TColumnSelectCommand::TColumnSelectCommand: Empty constructor to satisfy the compiler.
  3013. //----------------------------------------------------------------------------------------
  3014. #pragma segment ConstructorRes
  3015.  
  3016. TColumnSelectCommand::TColumnSelectCommand()
  3017. {
  3018. } // TColumnSelectCommand::TColumnSelectCommand
  3019.  
  3020. //----------------------------------------------------------------------------------------
  3021. // TColumnSelectCommand::IColumnSelectCommand: 
  3022. //----------------------------------------------------------------------------------------
  3023. #pragma segment GVSelCommand
  3024.  
  3025. void TColumnSelectCommand::IColumnSelectCommand(TGridView* itsView,
  3026.                                                        const VPoint& itsMouse,
  3027.                                                        Boolean theShiftKey,
  3028.                                                        Boolean theCommandKey)
  3029. {
  3030.     this->IRCSelectCommand(itsView, itsMouse, theShiftKey, theCommandKey);
  3031. } // TColumnSelectCommand::IColumnSelectCommand 
  3032.  
  3033. //----------------------------------------------------------------------------------------
  3034. // TColumnSelectCommand::ComputeAnchorCell: 
  3035. //----------------------------------------------------------------------------------------
  3036. #pragma segment GVDoCommand
  3037.  
  3038. void TColumnSelectCommand::ComputeAnchorCell(GridCell& clickedCell)// override 
  3039. {
  3040.     Inherited::ComputeAnchorCell(clickedCell);
  3041.  
  3042.     fAnchorCell.v = 1;
  3043. } // TColumnSelectCommand::ComputeAnchorCell 
  3044.  
  3045. //----------------------------------------------------------------------------------------
  3046. // TColumnSelectCommand::ComputeNewSelection: 
  3047. //----------------------------------------------------------------------------------------
  3048. #pragma segment GVDoCommand
  3049.  
  3050. void TColumnSelectCommand::ComputeNewSelection(GridCell& clickedCell)// override 
  3051. {
  3052.     clickedCell.v = fGridView->fNumOfRows;
  3053.  
  3054.     Inherited::ComputeNewSelection(clickedCell);
  3055. } // TColumnSelectCommand::ComputeNewSelection 
  3056.  
  3057.  
  3058. //========================================================================================
  3059. // CLASS CRowIterator
  3060. //========================================================================================
  3061. #undef Inherited
  3062. #define Inherited CIterator
  3063.  
  3064. const short CRowIterator::kNullRow = -1;
  3065.  
  3066. //----------------------------------------------------------------------------------------
  3067. // CRowIterator::CRowIterator:
  3068. //----------------------------------------------------------------------------------------
  3069. #pragma segment IteratorRes
  3070.  
  3071. CRowIterator::CRowIterator(TGridView* itsGridView,
  3072.                            short startRow,
  3073.                            short stopRow,
  3074.                            Boolean itsForward)
  3075. {
  3076.     this->IRowIterator(itsGridView, startRow, stopRow, itsForward);
  3077. } // CRowIterator::CRowIterator 
  3078.  
  3079.  
  3080. //----------------------------------------------------------------------------------------
  3081. // CRowIterator::CRowIterator: 
  3082. //----------------------------------------------------------------------------------------
  3083. #pragma segment IteratorRes
  3084.  
  3085. CRowIterator::CRowIterator(TGridView* itsGridView,
  3086.                            Boolean itsForward)
  3087. {
  3088.     this->IRowIterator(itsGridView, 1, itsGridView->fNumOfRows, itsForward);
  3089. } // CRowIterator::CRowIterator 
  3090.  
  3091.  
  3092. //----------------------------------------------------------------------------------------
  3093. // CRowIterator::CRowIterator: 
  3094. //----------------------------------------------------------------------------------------
  3095. #pragma segment IteratorRes
  3096.  
  3097. CRowIterator::CRowIterator(TGridView* itsGridView)
  3098. {
  3099.     this->IRowIterator(itsGridView, 1, itsGridView->fNumOfRows, kIterateForward);
  3100. } // CRowIterator::CRowIterator 
  3101.  
  3102.  
  3103. //----------------------------------------------------------------------------------------
  3104. // CRowIterator::IRowIterator: 
  3105. //----------------------------------------------------------------------------------------
  3106. #pragma segment IteratorRes
  3107.  
  3108. void CRowIterator::IRowIterator(TGridView* itsGridView,
  3109.                                 short startRow,
  3110.                                 short stopRow,
  3111.                                 Boolean itsForward)
  3112. {
  3113.     if (itsGridView)
  3114.     {
  3115.         fFirstRow = (short)Max(1, startRow);    //!!! Cast
  3116.         fLastRow = (short)Min(itsGridView->fNumOfRows, stopRow);//!!! Cast
  3117.         fIterateForward = itsForward;
  3118.         Reset();                                // this sets it to the beginning
  3119.     }
  3120.     else
  3121.     {
  3122.         fFirstRow = kNullRow;
  3123.         fLastRow = kNullRow;
  3124.         fIterateForward = kIterateForward;
  3125.         Reset();                                // this sets it to the beginning
  3126.     }
  3127. } // CRowIterator::IRowIterator 
  3128.  
  3129.  
  3130. //----------------------------------------------------------------------------------------
  3131. // CRowIterator::FirstRow: 
  3132. //----------------------------------------------------------------------------------------
  3133. #pragma segment IteratorRes
  3134.  
  3135. short CRowIterator::FirstRow()
  3136. {
  3137.     Reset();
  3138.     return fCurrentRow;
  3139. } // CRowIterator::FirstRow 
  3140.  
  3141.  
  3142. //----------------------------------------------------------------------------------------
  3143. // CRowIterator::NextRow: 
  3144. //----------------------------------------------------------------------------------------
  3145. #pragma segment IteratorRes
  3146.  
  3147. short CRowIterator::NextRow()
  3148. {
  3149.     if (this->More())                            // don't advance if we're at the end of the road!
  3150.         Advance();
  3151.     return fCurrentRow;
  3152. } // CRowIterator::NextRow 
  3153.  
  3154.  
  3155. //----------------------------------------------------------------------------------------
  3156. // CRowIterator::More: 
  3157. //----------------------------------------------------------------------------------------
  3158. #pragma segment IteratorRes
  3159.  
  3160. Boolean CRowIterator::More()
  3161. {
  3162.     return (fCurrentRow != kNullRow);
  3163. } // CRowIterator::More 
  3164.  
  3165.  
  3166. //----------------------------------------------------------------------------------------
  3167. // CRowIterator::Reset: 
  3168. //----------------------------------------------------------------------------------------
  3169. #pragma segment IteratorRes
  3170.  
  3171. void CRowIterator::Reset()
  3172. {
  3173.     if (fFirstRow <= fLastRow)
  3174.         if (fIterateForward)
  3175.             fCurrentRow = fFirstRow;
  3176.         else
  3177.             fCurrentRow = fLastRow;
  3178.     else
  3179.         fCurrentRow = kNullRow;                    // there is nothing to iterate over!
  3180. } // CRowIterator::Reset 
  3181.  
  3182. //----------------------------------------------------------------------------------------
  3183. // CRowIterator::Advance: 
  3184. //----------------------------------------------------------------------------------------
  3185. #pragma segment IteratorRes
  3186.  
  3187. void CRowIterator::Advance()
  3188. {
  3189.     //This assumes that More() is FALSE -- otherwise Advance() may start iterating
  3190.     //from 0, since kNullRow is most probably less than fLastRow
  3191.     if (fIterateForward)
  3192.     {
  3193.         if (fCurrentRow < fLastRow)
  3194.             ++fCurrentRow;
  3195.         else
  3196.             fCurrentRow = kNullRow;                // I know it's not really an index, but…
  3197.     }
  3198.     else
  3199.     {
  3200.         if (fCurrentRow > fFirstRow)
  3201.             --fCurrentRow;
  3202.         else
  3203.             fCurrentRow = kNullRow;
  3204.     }
  3205. } // CRowIterator::Advance 
  3206.  
  3207.  
  3208. //========================================================================================
  3209. // CLASS CColumnIterator
  3210. //========================================================================================
  3211. #undef Inherited
  3212. #define Inherited CIterator
  3213.  
  3214. const short CColumnIterator::kNullColumn = -1;
  3215.  
  3216. //----------------------------------------------------------------------------------------
  3217. // CColumnIterator::CColumnIterator:
  3218. //----------------------------------------------------------------------------------------
  3219. #pragma segment IteratorRes
  3220.  
  3221. CColumnIterator::CColumnIterator(TGridView* itsGridView,
  3222.                                  short startColumn,
  3223.                                  short stopColumn,
  3224.                                  Boolean itsForward)
  3225. {
  3226.     this->IColumnIterator(itsGridView, startColumn, stopColumn, itsForward);
  3227. } // CColumnIterator::CColumnIterator 
  3228.  
  3229. //----------------------------------------------------------------------------------------
  3230. // CColumnIterator::CColumnIterator: 
  3231. //----------------------------------------------------------------------------------------
  3232. #pragma segment IteratorRes
  3233.  
  3234. CColumnIterator::CColumnIterator(TGridView* itsGridView,
  3235.                                  Boolean itsForward)
  3236. {
  3237.     this->IColumnIterator(itsGridView, 1, itsGridView->fNumOfCols, itsForward);
  3238. } // CColumnIterator::CColumnIterator 
  3239.  
  3240. //----------------------------------------------------------------------------------------
  3241. // CColumnIterator::CColumnIterator: 
  3242. //----------------------------------------------------------------------------------------
  3243. #pragma segment IteratorRes
  3244.  
  3245. CColumnIterator::CColumnIterator(TGridView* itsGridView)
  3246. {
  3247.     this->IColumnIterator(itsGridView, 1, itsGridView->fNumOfCols, kIterateForward);
  3248. } // CColumnIterator::CColumnIterator 
  3249.  
  3250. //----------------------------------------------------------------------------------------
  3251. // CColumnIterator::IColumnIterator: 
  3252. //----------------------------------------------------------------------------------------
  3253. #pragma segment IteratorRes
  3254.  
  3255. void CColumnIterator::IColumnIterator(TGridView* itsGridView,
  3256.                                       short startColumn,
  3257.                                       short stopColumn,
  3258.                                       Boolean itsForward)
  3259. {
  3260.     if (itsGridView)
  3261.     {
  3262.         fFirstColumn = (short)Max(1, startColumn);//!!! Cast
  3263.         fLastColumn = (short)Min(itsGridView->fNumOfCols, stopColumn);//!!! Cast
  3264.         fIterateForward = itsForward;
  3265.         Reset();                                // this sets it to the beginning
  3266.     }
  3267.     else
  3268.     {
  3269.         fFirstColumn = kNullColumn;
  3270.         fLastColumn = kNullColumn;
  3271.         fIterateForward = kIterateForward;
  3272.         Reset();                                // this sets it to the beginning
  3273.     }
  3274. } // CColumnIterator::IColumnIterator
  3275.  
  3276. //----------------------------------------------------------------------------------------
  3277. // CColumnIterator::FirstColumn: 
  3278. //----------------------------------------------------------------------------------------
  3279. #pragma segment IteratorRes
  3280.  
  3281. short CColumnIterator::FirstColumn()
  3282. {
  3283.     Reset();
  3284.     return fCurrentColumn;
  3285. } // CColumnIterator::FirstColumn 
  3286.  
  3287. //----------------------------------------------------------------------------------------
  3288. // CColumnIterator::NextColumn: 
  3289. //----------------------------------------------------------------------------------------
  3290. #pragma segment IteratorRes
  3291.  
  3292. short CColumnIterator::NextColumn()
  3293. {
  3294.     if (this->More())                            // don't advance if we're at the end of the road!
  3295.         Advance();
  3296.     return fCurrentColumn;
  3297. } // CColumnIterator::NextColumn 
  3298.  
  3299. //----------------------------------------------------------------------------------------
  3300. // CColumnIterator::More: 
  3301. //----------------------------------------------------------------------------------------
  3302. #pragma segment IteratorRes
  3303.  
  3304. Boolean CColumnIterator::More()
  3305. {
  3306.     return (fCurrentColumn != kNullColumn);
  3307. } // CColumnIterator::More 
  3308.  
  3309. //----------------------------------------------------------------------------------------
  3310. // CColumnIterator::Reset: 
  3311. //----------------------------------------------------------------------------------------
  3312. #pragma segment IteratorRes
  3313.  
  3314. void CColumnIterator::Reset()
  3315. {
  3316.     if (fFirstColumn <= fLastColumn)
  3317.         if (fIterateForward)
  3318.             fCurrentColumn = fFirstColumn;
  3319.         else
  3320.             fCurrentColumn = fLastColumn;
  3321.     else
  3322.         fCurrentColumn = kNullColumn;            // there is nothing to iterate over!
  3323. } // CColumnIterator::Reset 
  3324.  
  3325. //----------------------------------------------------------------------------------------
  3326. // CColumnIterator::Advance: 
  3327. //----------------------------------------------------------------------------------------
  3328. #pragma segment IteratorRes
  3329.  
  3330. void CColumnIterator::Advance()
  3331. {
  3332.     //This assumes that More() is FALSE -- otherwise Advance() may start iterating
  3333.     //from 0, since kNullRow is most probably less than fLastRow
  3334.     if (fIterateForward)
  3335.     {
  3336.         if (fCurrentColumn < fLastColumn)
  3337.             ++fCurrentColumn;
  3338.         else
  3339.             fCurrentColumn = kNullColumn;        // I know it's not really an index, but…
  3340.     }
  3341.     else
  3342.     {
  3343.         if (fCurrentColumn > fFirstColumn)
  3344.             --fCurrentColumn;
  3345.         else
  3346.             fCurrentColumn = kNullColumn;
  3347.     }
  3348. } // CColumnIterator::Advance 
  3349.  
  3350.  
  3351. //========================================================================================
  3352. // CLASS CCellIterator
  3353. //========================================================================================
  3354. #undef Inherited
  3355. #define Inherited CIterator
  3356.  
  3357. const GridCell CCellIterator::kNullCell = GridCell(-1, -1);
  3358. const Boolean CCellIterator::kIterateRowMajor = TRUE;
  3359.  
  3360. //----------------------------------------------------------------------------------------
  3361. // CCellIterator::CCellIterator:
  3362. //----------------------------------------------------------------------------------------
  3363. #pragma segment IteratorRes
  3364.  
  3365. CCellIterator::CCellIterator(TGridView* itsGridView,
  3366.                              GridCell startCell,
  3367.                              GridCell stopCell,
  3368.                              Boolean itsRowForward,
  3369.                              Boolean itsColumnForward,
  3370.                              Boolean itsRowMajor) :
  3371.     // initialize the Row and Column Iterators first!
  3372.     fRowIterator(itsGridView, startCell.v, stopCell.v, itsRowForward),
  3373.     fColumnIterator(itsGridView, startCell.h, stopCell.h, itsColumnForward)
  3374.  
  3375. {
  3376.     fIterateRowMajor = itsRowMajor;                // don't worry about whether or not
  3377.                                                 // itsGridView is valid -- let the Row and
  3378.                                                 // Column Iterators worry about it.
  3379. } // CCellIterator::CCellIterator 
  3380.  
  3381. //----------------------------------------------------------------------------------------
  3382. // CCellIterator::CCellIterator: 
  3383. //----------------------------------------------------------------------------------------
  3384. #pragma segment IteratorRes
  3385.  
  3386. CCellIterator::CCellIterator(TGridView* itsGridView,
  3387.                              Boolean itsRowForward,
  3388.                              Boolean itsColumnForward,
  3389.                              Boolean itsRowMajor) :
  3390.     // initialize the Row and Column Iterators first!
  3391.     fRowIterator(itsGridView, itsRowForward),
  3392.     fColumnIterator(itsGridView, itsColumnForward)
  3393. {
  3394.     fIterateRowMajor = itsRowMajor;                // don't worry about whether or not
  3395.                                                 // itsGridView is valid -- let the Row and
  3396.                                                 // Column Iterators worry about it.
  3397. } // CCellIterator::CCellIterator 
  3398.  
  3399. //----------------------------------------------------------------------------------------
  3400. // CCellIterator::CCellIterator: 
  3401. //----------------------------------------------------------------------------------------
  3402. #pragma segment IteratorRes
  3403.  
  3404. CCellIterator::CCellIterator(TGridView* itsGridView) :
  3405.     // initialize the Row and Column Iterators first!
  3406.     fRowIterator(itsGridView),
  3407.     fColumnIterator(itsGridView)
  3408. {
  3409.     fIterateRowMajor = kIterateRowMajor;        // don't worry about whether or not
  3410.                                                 // itsGridView is valid -- let the Row and
  3411.                                                 // Column Iterators worry about it.
  3412. } // CCellIterator::CCellIterator 
  3413.  
  3414. //----------------------------------------------------------------------------------------
  3415. // CCellIterator::FirstCell: 
  3416. //----------------------------------------------------------------------------------------
  3417. #pragma segment IteratorRes
  3418.  
  3419. GridCell CCellIterator::FirstCell()
  3420. {
  3421.     this->Reset();
  3422.     return fCurrentCell;
  3423. } // CCellIterator::FirstCell 
  3424.  
  3425. //----------------------------------------------------------------------------------------
  3426. // CCellIterator::NextCell: 
  3427. //----------------------------------------------------------------------------------------
  3428. #pragma segment IteratorRes
  3429.  
  3430. GridCell CCellIterator::NextCell()
  3431. {
  3432.     this->Advance();
  3433.     return fCurrentCell;
  3434. } // CCellIterator::NextCell 
  3435.  
  3436. //----------------------------------------------------------------------------------------
  3437. // CCellIterator::More: 
  3438. //----------------------------------------------------------------------------------------
  3439. #pragma segment IteratorRes
  3440.  
  3441. Boolean CCellIterator::More()
  3442. {
  3443.     return (fRowIterator.More() || fColumnIterator.More());
  3444. } // CCellIterator::More 
  3445.  
  3446. //----------------------------------------------------------------------------------------
  3447. // CCellIterator::Reset: 
  3448. //----------------------------------------------------------------------------------------
  3449. #pragma segment IteratorRes
  3450.  
  3451. void CCellIterator::Reset()
  3452. {
  3453.     fCurrentCell.v = fRowIterator.FirstRow();
  3454.     fCurrentCell.h = fColumnIterator.FirstColumn();
  3455. } // CCellIterator::Reset 
  3456.  
  3457. //----------------------------------------------------------------------------------------
  3458. // CCellIterator::Advance: 
  3459. //----------------------------------------------------------------------------------------
  3460. #pragma segment IteratorRes
  3461.  
  3462. void CCellIterator::Advance()
  3463. {
  3464.     if (fIterateRowMajor)
  3465.     {
  3466.         fCurrentCell.h = fColumnIterator.NextColumn();//advance the column
  3467.         if (!fColumnIterator.More())
  3468.         {
  3469.             fCurrentCell.v = fRowIterator.NextRow();//advance the row
  3470.             if (fRowIterator.More())            //must go through the columns again
  3471.             {
  3472.                 fCurrentCell.h = fColumnIterator.FirstColumn();
  3473.             }
  3474.         }
  3475.     }
  3476.     else
  3477.     {
  3478.         fCurrentCell.v = fRowIterator.NextRow();//advance the row
  3479.         if (!fRowIterator.More())
  3480.         {
  3481.             fCurrentCell.h = fColumnIterator.NextColumn();//advance the column
  3482.             if (fColumnIterator.More())            //must go through the rows again
  3483.             {
  3484.                 fCurrentCell.v = fRowIterator.FirstRow();
  3485.             }
  3486.         }
  3487.     }
  3488. } // CCellIterator::Advance 
  3489.  
  3490.  
  3491.  
  3492. //========================================================================================
  3493. // CLASS CCellInRegionIterator
  3494. //========================================================================================
  3495. #undef Inherited
  3496. #define Inherited CCellIterator
  3497.  
  3498. //----------------------------------------------------------------------------------------
  3499. // CCellInRegionIterator::CCellInRegionIterator: an iterator class designed to replace the
  3500. // EachInRegion method of TGridView. APW 7-15
  3501. //----------------------------------------------------------------------------------------
  3502. #pragma segment IteratorRes
  3503.  
  3504. CCellInRegionIterator::CCellInRegionIterator(TGridView* itsGridView,
  3505.                                              RgnHandle aRegion,
  3506.                                              Boolean itsRowForward,
  3507.                                              Boolean itsColumnForward,
  3508.                                              Boolean itsRowMajor) :
  3509.     CCellIterator(itsGridView, 
  3510.                   ((CRect &) (*aRegion)->rgnBBox)[topLeft], 
  3511.                   ((CRect &) (*aRegion)->rgnBBox)[botRight] - CPoint(1, 1), 
  3512.                   itsRowForward, itsColumnForward, itsRowMajor)
  3513. {
  3514.     fIsRectangularRegion = ((**aRegion).rgnSize == 10);// it's a Rectangle
  3515.     fRegion = aRegion;
  3516. } // CCellInRegionIterator::CCellInRegionIterator 
  3517.  
  3518. //----------------------------------------------------------------------------------------
  3519. // CCellInRegionIterator::CCellInRegionIterator: 
  3520. //----------------------------------------------------------------------------------------
  3521. #pragma segment IteratorRes
  3522.  
  3523. CCellInRegionIterator::CCellInRegionIterator(TGridView* itsGridView,
  3524.                                              RgnHandle aRegion) :
  3525.     CCellIterator(itsGridView, 
  3526.                   ((CRect &) (*aRegion)->rgnBBox)[topLeft], 
  3527.                   ((CRect &) (*aRegion)->rgnBBox)[botRight] - CPoint(1, 1), 
  3528.                   kIterateForward, kIterateForward, kIterateRowMajor)
  3529. {
  3530.     fIsRectangularRegion = ((**aRegion).rgnSize == 10);// it's a Rectangle
  3531.     fRegion = aRegion;
  3532. } // CCellInRegionIterator::CCellInRegionIterator 
  3533.  
  3534. //----------------------------------------------------------------------------------------
  3535. // CCellInRegionIterator::Reset: 
  3536. //----------------------------------------------------------------------------------------
  3537. #pragma segment IteratorRes
  3538.  
  3539. void CCellInRegionIterator::Reset()            //override!
  3540. {
  3541.     CCellIterator::Reset();                        // should be Inherited::Reset
  3542.  
  3543.     if (!fIsRectangularRegion)                    // if it's rectangular, all cells are in
  3544.                                                 // the region.
  3545.     {
  3546.         if ((this->More()) &&!CellIsInRegion())    // Otherwise, check to see if it's in the
  3547.                                                 // region.
  3548.             this->Advance();                    // This is now guaranteed to be a selected
  3549.                                                 // cell
  3550.     }
  3551. } // CCellInRegionIterator::Reset 
  3552.  
  3553. //----------------------------------------------------------------------------------------
  3554. // CCellInRegionIterator::Advance: 
  3555. //----------------------------------------------------------------------------------------
  3556. #pragma segment IteratorRes
  3557. void CCellInRegionIterator::Advance()        //override!
  3558.  
  3559. {
  3560.     CCellIterator::Advance();                    //first advance
  3561.  
  3562.     if (!fIsRectangularRegion)                    // do we have to check to see if it is
  3563.                                                 // selected?
  3564.     {
  3565.         while ((this->More()) &&!CellIsInRegion())
  3566.         {
  3567.                                                 // Yes, so while we have an
  3568.                                                 // unselected cell, keep 
  3569.                                                 // iterating until we
  3570.             CCellIterator::Advance();            // run out or find one.
  3571.         }
  3572.     }
  3573. } // CCellInRegionIterator::Advance 
  3574.  
  3575. //----------------------------------------------------------------------------------------
  3576. // CCellInRegionIterator::CellIsInRegion: 
  3577. //----------------------------------------------------------------------------------------
  3578. #pragma segment IteratorRes
  3579. Boolean CCellInRegionIterator::CellIsInRegion()
  3580.  
  3581. {
  3582.     return PtInRgn(fCurrentCell, fRegion);
  3583. } // CCellInRegionIterator::CellIsInRegion 
  3584.  
  3585.  
  3586. //========================================================================================
  3587. // CLASS CSelectedCellIterator
  3588. //========================================================================================
  3589. #undef Inherited
  3590. #define Inherited CCellInRegionIterator
  3591.  
  3592. //----------------------------------------------------------------------------------------
  3593. // CSelectedCellIterator::CSelectedCellIterator: an iterator class designed to replace the
  3594. // EachSelectedCellDo method of TGridView. APW 7-15
  3595. //----------------------------------------------------------------------------------------
  3596. #pragma segment IteratorRes
  3597. CSelectedCellIterator::CSelectedCellIterator(TGridView* itsGridView,
  3598.                                              Boolean itsRowForward,
  3599.                                              Boolean itsColumnForward,
  3600.                                              Boolean itsRowMajor) :
  3601.     CCellInRegionIterator(itsGridView, itsGridView->fSelections, itsRowForward, itsColumnForward, itsRowMajor)
  3602. {
  3603. } // CSelectedCellIterator::CSelectedCellIterator 
  3604.  
  3605. //----------------------------------------------------------------------------------------
  3606. // CSelectedCellIterator::CSelectedCellIterator: 
  3607. //----------------------------------------------------------------------------------------
  3608. #pragma segment IteratorRes
  3609. CSelectedCellIterator::CSelectedCellIterator(TGridView* itsGridView) :
  3610.     CCellInRegionIterator(itsGridView, itsGridView->fSelections)
  3611. {
  3612. } // CSelectedCellIterator::CSelectedCellIterator 
  3613.  
  3614.